Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Julian Scheid
On Wed, Mar 17, 2010 at 4:43 PM, Michael Bayer  wrote:
>
> On Mar 16, 2010, at 11:24 PM, Julian Scheid wrote:
>
>> On Wed, Mar 17, 2010 at 4:15 PM, Michael Bayer  
>> wrote:
>>> if your cleanup handler only expires connections that are older than the 
>>> "pool_expire" time, that should help.
>>
>> Sorry, I don't follow - what is pool_expire and where is it used? I
>> don't see a reference to that in
>> http://www.sqlalchemy.org/trac/browser/lib/sqlalchemy/pool.py or in
>> the docs, and a Google search comes up empty.
>
> sorry I meant "recycle".  its "pool_recycle" on create_engine().

Oh, right - that makes sense. Yes, it looks like this way I can avoid
synchronisation.

Thank you.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Michael Bayer

On Mar 16, 2010, at 11:24 PM, Julian Scheid wrote:

> On Wed, Mar 17, 2010 at 4:15 PM, Michael Bayer  
> wrote:
>> if your cleanup handler only expires connections that are older than the 
>> "pool_expire" time, that should help.
> 
> Sorry, I don't follow - what is pool_expire and where is it used? I
> don't see a reference to that in
> http://www.sqlalchemy.org/trac/browser/lib/sqlalchemy/pool.py or in
> the docs, and a Google search comes up empty.

sorry I meant "recycle".  its "pool_recycle" on create_engine().





> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Julian Scheid
On Wed, Mar 17, 2010 at 4:15 PM, Michael Bayer  wrote:
> if your cleanup handler only expires connections that are older than the 
> "pool_expire" time, that should help.

Sorry, I don't follow - what is pool_expire and where is it used? I
don't see a reference to that in
http://www.sqlalchemy.org/trac/browser/lib/sqlalchemy/pool.py or in
the docs, and a Google search comes up empty.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Michael Bayer

On Mar 16, 2010, at 10:25 PM, Julian Scheid wrote:

> On Wed, Mar 17, 2010 at 3:10 PM, Michael Bayer  
> wrote:
>> Well the pool only holds at one time the number of connections that you 
>> configure - it has an "overflow" of connections if more are requested but 
>> those aren't held around.
> 
> Yep, but "overflow" connections are discarded immediately and other
> connections are held indefinitely - I'm looking for something in
> between.
> 
>> But as you mentioned, it seems you're really looking for a thread here that 
>> will reduce the size of the pool asynchronously, so simple enough to just 
>> run a background thread which iterates through the pool calling invalidate() 
>> on connections older than 30 seconds.   Its likely a 10 liner.   I'd 
>> appreciate if you can put it up on the UsageRecipes wiki page if you have 
>> success.
> 
> Sure, I'm happy to do that.
> 
> I realize there's not a lot of code involved but in my experience
> everything that involves concurrency can be a bit tricky to get right,
> what with race conditions and all, which is why I was hoping for an
> existing, proven solution. Oh well, I'll see what I can come up with.

if your cleanup handler only expires connections that are older than the 
"pool_expire" time, that should help.




> 
> Thanks again,
> 
> Julian
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Julian Scheid
On Wed, Mar 17, 2010 at 3:10 PM, Michael Bayer  wrote:
> Well the pool only holds at one time the number of connections that you 
> configure - it has an "overflow" of connections if more are requested but 
> those aren't held around.

Yep, but "overflow" connections are discarded immediately and other
connections are held indefinitely - I'm looking for something in
between.

> But as you mentioned, it seems you're really looking for a thread here that 
> will reduce the size of the pool asynchronously, so simple enough to just run 
> a background thread which iterates through the pool calling invalidate() on 
> connections older than 30 seconds.   Its likely a 10 liner.   I'd appreciate 
> if you can put it up on the UsageRecipes wiki page if you have success.

Sure, I'm happy to do that.

I realize there's not a lot of code involved but in my experience
everything that involves concurrency can be a bit tricky to get right,
what with race conditions and all, which is why I was hoping for an
existing, proven solution. Oh well, I'll see what I can come up with.

Thanks again,

Julian

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Michael Bayer

On Mar 16, 2010, at 9:46 PM, Julian Scheid wrote:

> 
> I'm not sure if Connection.invalidate helps a lot either, as
> invalidation/expiry should depend on when the connection was returned
> to the pool so it seems that putting this functionality into a custom
> Pool implementation is more appropriate.
> 
> Does this make sense, am I missing something?

Well the pool only holds at one time the number of connections that you 
configure - it has an "overflow" of connections if more are requested but those 
aren't held around.

But as you mentioned, it seems you're really looking for a thread here that 
will reduce the size of the pool asynchronously, so simple enough to just run a 
background thread which iterates through the pool calling invalidate() on 
connections older than 30 seconds.   Its likely a 10 liner.   I'd appreciate if 
you can put it up on the UsageRecipes wiki page if you have success.





> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Julian Scheid
On Wed, Mar 17, 2010 at 2:46 PM, Julian Scheid  wrote:
> Does this make sense, am I missing something?

I guess I'm looking for something akin to the "idle object evictor
thread" mentioned here:
http://commons.apache.org/dbcp/configuration.html

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Julian Scheid
On Wed, Mar 17, 2010 at 2:31 PM, Michael Bayer  wrote:
>
> On Mar 16, 2010, at 8:09 PM, Julian Scheid wrote:
>
>> I'm looking for a way to close a pooled connection client-side after a
>> certain period, say when it wasn't used in 30 seconds. I don't think
>> any of the Pool implementations that come with SQLAlchemy supports
>> this. Does anybody know of a third-party implementation with this
>> functionality? I guess it wouldn't be difficult to create one from
>> scratch but I was hoping that there is an existing solution.
>
>
> *All* of the pool implementations support this, with the caveat that its 
> recycled on next checkout.  See "pool_recycle" at 
> http://www.sqlalchemy.org/docs/reference/sqlalchemy/connections.html?highlight=create_engine#sqlalchemy.create_engine
>  .
>
> You can also force any connection to recycle immediately using 
> connection.invalidate():
>
> http://www.sqlalchemy.org/docs/reference/sqlalchemy/connections.html?highlight=create_engine#sqlalchemy.create_engine
>
> if you truly wanted a checked out connection to automatically invalidate 
> itself while checked out,  you definitely need to forego using any 
> transactions with it (i.e. autocommit for everything), and you can create a 
> ConnectionProxy that calls invalidate() when an execute() call is received 
> more than 30 seconds since the last one.  ConnectionProxy is at 
> http://www.sqlalchemy.org/docs/reference/sqlalchemy/interfaces.html#sqlalchemy.interfaces.ConnectionProxy
>  .

Thanks for your reply. To elaborate a bit, this is meant to reduce the
number of open database connections held by long-lived clients that do
not continuously access the database (while still avoiding having to
open a new physical connection for every session when there are
multiple sessions in quick succession.)

I do not need to invalidate checked out connections - I would like to
close connections that have been returned to the pool and have been
sitting there for a while without being re-requested.

If I understand recycling correctly, it doesn't really help with this
as it only closes the connection right before opening another one.

I'm not sure if Connection.invalidate helps a lot either, as
invalidation/expiry should depend on when the connection was returned
to the pool so it seems that putting this functionality into a custom
Pool implementation is more appropriate.

Does this make sense, am I missing something?

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Expiring pooled connections

2010-03-16 Thread Michael Bayer

On Mar 16, 2010, at 8:09 PM, Julian Scheid wrote:

> I'm looking for a way to close a pooled connection client-side after a
> certain period, say when it wasn't used in 30 seconds. I don't think
> any of the Pool implementations that come with SQLAlchemy supports
> this. Does anybody know of a third-party implementation with this
> functionality? I guess it wouldn't be difficult to create one from
> scratch but I was hoping that there is an existing solution.


*All* of the pool implementations support this, with the caveat that its 
recycled on next checkout.  See "pool_recycle" at 
http://www.sqlalchemy.org/docs/reference/sqlalchemy/connections.html?highlight=create_engine#sqlalchemy.create_engine
 .

You can also force any connection to recycle immediately using 
connection.invalidate():

http://www.sqlalchemy.org/docs/reference/sqlalchemy/connections.html?highlight=create_engine#sqlalchemy.create_engine

if you truly wanted a checked out connection to automatically invalidate itself 
while checked out,  you definitely need to forego using any transactions with 
it (i.e. autocommit for everything), and you can create a ConnectionProxy that 
calls invalidate() when an execute() call is received more than 30 seconds 
since the last one.  ConnectionProxy is at 
http://www.sqlalchemy.org/docs/reference/sqlalchemy/interfaces.html#sqlalchemy.interfaces.ConnectionProxy
 .



> 
> Thanks,
> 
> Julian
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to 
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: ms sql server schema.sequence

2010-03-16 Thread Michael Trier
Hello Tan,

On Mar 16, 2010, at 7:57 PM, Tan Yi wrote:

> I mean, I tried to debug a program, using session add() to insert new
> records to database after I deleted all the old records from a table.
> I used the schema.sequence() to build up a mapper
> Can anyone help?
> 
> On 3月16日, 下午2时05分, Tan Yi  wrote:
>> Whenever I try to use schema.sequence() function on ms sql server, the
>> return serial number (after flush())  is not started from 0, instead,
>> it is started from a random number or something.
>> wondering how to work aroud this issue. try to specify start = 0 in
>> sequence function, but no luck

With MSSQL whenever you delete records from a table it does not reset the 
IDENTITY.  If you would like the identity to reset back to one (zero is not an 
option), then you need to truncate the table with:

TRUNCATE TABLE tablename;

If this is not the issue then it might be helpful if you provide a test case 
that demonstrates the issue you are having. It will be easier to diagnose that 
way.

Michael

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Expiring pooled connections

2010-03-16 Thread Julian Scheid
I'm looking for a way to close a pooled connection client-side after a
certain period, say when it wasn't used in 30 seconds. I don't think
any of the Pool implementations that come with SQLAlchemy supports
this. Does anybody know of a third-party implementation with this
functionality? I guess it wouldn't be difficult to create one from
scratch but I was hoping that there is an existing solution.

Thanks,

Julian

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: ms sql server schema.sequence

2010-03-16 Thread Tan Yi
I mean, I tried to debug a program, using session add() to insert new
records to database after I deleted all the old records from a table.
I used the schema.sequence() to build up a mapper
Can anyone help?

On 3月16日, 下午2时05分, Tan Yi  wrote:
> Whenever I try to use schema.sequence() function on ms sql server, the
> return serial number (after flush())  is not started from 0, instead,
> it is started from a random number or something.
> wondering how to work aroud this issue. try to specify start = 0 in
> sequence function, but no luck

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] ms sql server schema.sequence

2010-03-16 Thread Tan Yi
Whenever I try to use schema.sequence() function on ms sql server, the
return serial number (after flush())  is not started from 0, instead,
it is started from a random number or something.
wondering how to work aroud this issue. try to specify start = 0 in
sequence function, but no luck

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] composite index using declarative

2010-03-16 Thread Daniel Robbins
On Tue, Mar 16, 2010 at 10:29 AM, Michael Bayer
 wrote:
> Daniel Robbins wrote:
>
>> People want to *start* with declarative, whereas you
>> as the architect started with the core parts of the framework and
>> recently added declarative. So you know all the underpinnings, but
>> most users don't, and they want to remain on as high a level
>> (declarative) as possible without having to get sidetracked by being
>> forced to master the lower-level parts in order to simply create an
>> index for their declarative tables. Make sense? How to tie the two
>> together is not always documented clearly. Think from the new user's
>> perspective and try to accommodate them via the docs.
>
> I appreciate the rant but we're only talking about adding a distinct
> section to the declarative documentation regarding indexes, which is
> already accepted, and specific examples regarding remote_side and such are
> non-controversial as well and we shall review the cases you present.

I'm not ranting, I'm offering constructive, critical feedback for your
excellent project.

> It doesn't make much sense for the declarative documentation to completely
> duplicate the entire mapping/relation/metadata sections of the
> documentation, however.

Complete duplication is not required. However. I've written a lot of
technical documentation, and I've found that some repetition, and
building upon ideas introduced in other sections, does make technical
documentation much easier to use.

>> Index('endp_grp_ix', Endpoint.__table__.c.samplegroup_id,
>> Endpoint.__table__.c.name)
>
> Index to my knowledge does accept declarative columns these days.  You can
> pass in Endpoint.samplegroup_id and Endpoint.name directly.  The above
> workaround was for a bug.

Then this should be documented in the declarative section, with an example.

>> Host.interfaces = relation("HostInterface",
>> collection_class=column_mapped_collection(HostInterface.name))
>
> I'm not aware of this requirement.  you should be able to create the
> "interfaces" relation inside of Host, using a string to define
> "collection_class" or otherwise use attribute_mapped_collection("name").
> If this is not possible, then its a bug.

Looks like a bug in 0.6_beta1 then:

Traceback (most recent call last):
  File "base.py", line 525, in 
class HostInterface(Base):
  File "base.py", line 533, in HostInterface
interfaces = relation('HostInterface',
collection_class=column_mapped_collection('HostInterface.name'))
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/collections.py",
line 132, in column_mapped_collection
cols = [expression._no_literals(q) for q in util.to_list(mapping_spec)]
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/sql/expression.py",
line 980, in _no_literals
"to indicate a SQL expression literal, or 'literal()' to indicate
a bound value." % element)
sqlalchemy.exc.ArgumentError: Ambiguous literal: 'HostInterface.name'.
 Use the 'text()' function to indicate a SQL expression literal, or
'literal()' to indicate a bound value.

Regardless, documentation in the declarative section about how to do
this cleanly would be appreciated.

> I wouldn't consider Oracle to be a good candidate for "diving in".  But we
> do have a prominent sidebox in the ORM tutorial now, describing the need
> for the Sequence construct when using Firebird or Oracle, which you can
> see at
> http://www.sqlalchemy.org/docs/ormtutorial.html#define-and-create-a-table

That is a great addition.

> I'd note that the metaclass stuff you've done has been worked into a
> simple built in feature, using our new "mixin" capability, which is
> described at:

I think Mix-Ins are a great idea and very elegant, and I'm very
thankful they were added by Chris, but again in this case, more
complex examples would be extremely helpful.

If you look closely at what I am trying to do -- naming the primary
key sequence based on the name of the table -- Mix-Ins provide no
obvious mechanism to do this, since I need to create the primary key
and sequence "on the fly" after the table name is provided. With the
primary key in the base class and the table name in the sub-class,
this becomes problematic.

If you know how to implement the code I provided using a Mix-in, then
I'd love to see an example on this mailing list, or even better, in
the docs :)

Regarding Oracle, if someone only has Oracle to work with, or wants to
create an Oracle-based solution, then they need to figure out how to
do sophisticated things like this in order to get meaningful work done
with SQLAlchemy and feel comfortable with the framework. I don't think
the extra code or design philosophy of SQLAlchemy is an issue, it's
the time required to harvest the necessary info from the docs and
compile it into a working skeleton. Once the skeleton has been
assembled, SQLAlchemy is a joy to use.

> We mention prominently in the intro and on the wiki that there's a place
> for recipes like these, which is the UsageRecipes section:
>
>

Re: [sqlalchemy] using in_ against multiple columns

2010-03-16 Thread Manlio Perillo
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

richard reitmeyer ha scritto:
> Hello, all.
> 
> I'm trying to use compound fields with in_ to achieve something like
> this:
> 
> update foo set svrid = NULL, asof=NULL
> where (svrid,asof)
>   in (select svrid, asof from foo except select svrid,
> asof from bar);
> 

If you are using PostgreSQL, you can use the ROW constructor.


Regards  Manlio
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkufw6wACgkQscQJ24LbaUTiuQCfUhN26bZA7FTzWZK8wWYl7L73
q8MAn0vu60420NU9DwPlGQCdl2EuSNAA
=fEMJ
-END PGP SIGNATURE-

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] composite index using declarative

2010-03-16 Thread Michael Bayer
Daniel Robbins wrote:
> On Tue, Mar 16, 2010 at 8:08 AM, Michael Bayer 
> wrote:
>>
>> we definitely should because I am amazed at how often this question gets
>> asked.   But the more puzzling thing is that it means the central tenet
>> of
>> declarative isn't getting across to people, which is that nothing
>> changes
>> at all when using declarative, its strictly a syntactical shortcut -
>> everything you do when not using declarative is still 100% doable, in
>> exactly the same way.  I'm not sure why I see so many questions from
>> others of the form "but I'm using declarative!"
>
> My advice to you is to embrace the feedback and use it to make the
> project better.

I'm sure if you review our mailing list history for the past five years
you'll be pleased to know that the virtually all of the progress made on
the SQLAlchemy project post version 0.1 has been driven completely by
end-user need, but at the same time not turning the project into a
PHP-soup of flags and switches, distilling what end users need into an
ever expanding but coherent system that attempts to be as consistent as
possible.Rest assured that if we didn't do a pretty good job of
balancing these sides we wouldn't still be a prominent project today.

> People want to *start* with declarative, whereas you
> as the architect started with the core parts of the framework and
> recently added declarative. So you know all the underpinnings, but
> most users don't, and they want to remain on as high a level
> (declarative) as possible without having to get sidetracked by being
> forced to master the lower-level parts in order to simply create an
> index for their declarative tables. Make sense? How to tie the two
> together is not always documented clearly. Think from the new user's
> perspective and try to accommodate them via the docs.

I appreciate the rant but we're only talking about adding a distinct
section to the declarative documentation regarding indexes, which is
already accepted, and specific examples regarding remote_side and such are
non-controversial as well and we shall review the cases you present.

Declarative doesn't *require* that arguments are passed as strings,
either, this is optional.  There's some discussion of some common gotchas
here on the FAQ at
http://www.sqlalchemy.org/trac/wiki/FAQ#ImusingDeclarativeandsettingprimaryjoinsecondaryjoinusinganand_oror_andIamgettinganerrormessageaboutforeignkeys
, but we can integrate this into the declarative docs too.

It doesn't make much sense for the declarative documentation to completely
duplicate the entire mapping/relation/metadata sections of the
documentation, however.   It's still expected that users who want to deal
with Index, Sequence, etc. constructs will have read these sections.  
Better hyperlinking, a constant work in progress (and very open to outside
contribution via patches, we transitioned to Sphinx largely for this
reason) also makes the docs easier to follow.


>
> Index('endp_grp_ix', Endpoint.__table__.c.samplegroup_id,
> Endpoint.__table__.c.name)

Index to my knowledge does accept declarative columns these days.  You can
pass in Endpoint.samplegroup_id and Endpoint.name directly.  The above
workaround was for a bug.

> # But it would be nice to access them as a dictionary, so we could
> grab a particular interface by typing:
> # myhost.interfaces["eth0"]. Here's how we create an "interfaces"
> reference in dictionary mode. This must be done
> # outside of the class after both tables have been defined:
>
> Host.interfaces = relation("HostInterface",
> collection_class=column_mapped_collection(HostInterface.name))

I'm not aware of this requirement.  you should be able to create the
"interfaces" relation inside of Host, using a string to define
"collection_class" or otherwise use attribute_mapped_collection("name"). 
If this is not possible, then its a bug.

> I am working on a pretty simple DB project, with only about 12 tables,
> but here is my supporting/helper code, which is an order of magnitude
> more complex than the samples in the docs, but got declarative to the
> point where 1) I could actually use it with Oracle by adding
> auto-sequences to the declarative model (a BIG hurdle for new users
> who just want to dive in and are using it with a db that doesn't have
> auto-increment sequences)

I wouldn't consider Oracle to be a good candidate for "diving in".  But we
do have a prominent sidebox in the ORM tutorial now, describing the need
for the Sequence construct when using Firebird or Oracle, which you can
see at
http://www.sqlalchemy.org/docs/ormtutorial.html#define-and-create-a-table
.

> and 2) where I could significantly reduce
> duplicated code, which is generally one of the benefits of using a
> class heirarchy.
>
> It took me quite a bit of time to piece this all together, where more
> complex examples in the docs would have helped me along:

I'd note that the metaclass stuff you've done has been worked into a
simple built in feature, 

Re: [sqlalchemy] composite index using declarative

2010-03-16 Thread Daniel Robbins
On Tue, Mar 16, 2010 at 8:08 AM, Michael Bayer  wrote:
>
> we definitely should because I am amazed at how often this question gets
> asked.   But the more puzzling thing is that it means the central tenet of
> declarative isn't getting across to people, which is that nothing changes
> at all when using declarative, its strictly a syntactical shortcut -
> everything you do when not using declarative is still 100% doable, in
> exactly the same way.  I'm not sure why I see so many questions from
> others of the form "but I'm using declarative!"

My advice to you is to embrace the feedback and use it to make the
project better. People want to *start* with declarative, whereas you
as the architect started with the core parts of the framework and
recently added declarative. So you know all the underpinnings, but
most users don't, and they want to remain on as high a level
(declarative) as possible without having to get sidetracked by being
forced to master the lower-level parts in order to simply create an
index for their declarative tables. Make sense? How to tie the two
together is not always documented clearly. Think from the new user's
perspective and try to accommodate them via the docs.

I'm including a bunch of my sample code below, which you are welcome
to use in the docs or SQLAlchemy itself. This stuff deals with table
creation - you also need more examples for queries, but I don't have
enough useful examples stored up for those yet.

Here's one thing that was tricky to figure out - a self-referencing
table using declarative. Tricky because of the "remote_side" reference
using a string:

# The following code implements a self-referencing, heirarchical
table, and is tricky code
# to figure out for SQLAlchemy. You can append children to .children
or choose to create the
# child first and set its parent. Commit one and the parent/children
should be committed
# too.

class Location(Base):
__tablename__ = 'location'
parent_id = Column(Integer, ForeignKey('location.id'))
parent = relation('Location', backref=backref('children'),
remote_side='location.c.id')
name = UniqueString(25)
desc = Column(String(80))

Below, there are some examples of "bridging the divide" between
non-declarative and declarative use, to show people how to do it. It's
much easier to understand how to do this when you can actually see
code that does it. A lot of the examples in the docs are somewhat
trivial and don't really show you how the pieces fit together, such as
this example below, which shows how to reference __table__:

class Endpoint(Base):
__tablename__ = 'endp'
__table_args__ = [
UniqueConstraint( 'samplegroup_id', 'name' ),
]
samplegroup_id, samplegroup = ManyToOne(SampleGroup, nullable=False)
name = Column(String(80), nullable=False)
os_id, os = ManyToOne(EndpointOSType, nullable=False)

Index('endp_grp_ix', Endpoint.__table__.c.samplegroup_id,
Endpoint.__table__.c.name)

Here is another much-needed example:

# this table has a "peer_id" which can reference another
HostInterface. myhostinterface.peer will reference this peer, or
# None if no peer is set in peer_id. There is a backref to from the
peer back to myhostinferface using the .peered backref.
#

class HostInterface(Base):
__tablename__ = 'host_i'
name = Column(String(20), nullable=False)
host_id, host = ManyToOne(Host, nullable=False )
hostmac_id, hostmac = ManyToOne(HostMAC, nullable=False)
peer_id = Column(Integer, ForeignKey('host_i.id'), index=True)
peer = relation('HostInterface', backref=backref('peered'),
remote_side='host_i.c.id')
ip_id, ip = ManyToOne(IP)

class Host(Base):
__tablename__ = 'host'
owner_id, owner = ManyToOne(User, nullable=False, index=True)
type = Column(String(1), nullable=False)
hostid = UniqueString()

#Our host can have many HostInterfaces. By default, SQLAlchemy would
allow us to reference them as a list, such as:
# for int in myhost.interfaces:
#print int
# But it would be nice to access them as a dictionary, so we could
grab a particular interface by typing:
# myhost.interfaces["eth0"]. Here's how we create an "interfaces"
reference in dictionary mode. This must be done
# outside of the class after both tables have been defined:

Host.interfaces = relation("HostInterface",
collection_class=column_mapped_collection(HostInterface.name))

I am working on a pretty simple DB project, with only about 12 tables,
but here is my supporting/helper code, which is an order of magnitude
more complex than the samples in the docs, but got declarative to the
point where 1) I could actually use it with Oracle by adding
auto-sequences to the declarative model (a BIG hurdle for new users
who just want to dive in and are using it with a db that doesn't have
auto-increment sequences) and 2) where I could significantly reduce
duplicated code, which is generally 

Re: [sqlalchemy] composite index using declarative

2010-03-16 Thread Michael Bayer
Daniel Robbins wrote:
> On Mar 15, 2010, at 4:58 PM, Michael Bayer wrote:
>> we have some index examples at
>> http://www.sqlalchemy.org/docs/metadata.html#indexes .  the Index is not
>> related to declarative and is specified separately.
>
> Any plans to improve this? I would have thought that Indexes would be
> defined under __table_args__ along with constraints, which are often
> related.

the word "improve" here makes me smile.   Its the way it is intentionally
to look the way table DDL does.   We could make the Index construct
capable of accepting non-table bound columns in its constructor which
would allow you to stick it within your declarative class before the Table
is generated...but we're literally talking about allowing a single indent.

>
> Since Index creation is such a common need, and the current means of
> creating one is counter-intuitive, do you think you could add a sample
> Index code snippet to the declarative documentation?

we definitely should because I am amazed at how often this question gets
asked.   But the more puzzling thing is that it means the central tenet of
declarative isn't getting across to people, which is that nothing changes
at all when using declarative, its strictly a syntactical shortcut -
everything you do when not using declarative is still 100% doable, in
exactly the same way.  I'm not sure why I see so many questions from
others of the form "but I'm using declarative!"


>
> -Daniel
>
> --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] using in_ against multiple columns

2010-03-16 Thread Michael Bayer
richard reitmeyer wrote:
> Hello, all.
>
> I'm trying to use compound fields with in_ to achieve something like
> this:
>
> update foo set svrid = NULL, asof=NULL
> where (svrid,asof)
>   in (select svrid, asof from foo except select svrid,
> asof from bar);
>
> Use case is cleaning up entries in foo records that refer to damaged
> or missing bar records, where the check is against a column pair. I'm
> expecting ~99% of the records in foo to have a correspondence to
> something in bar.
>
> My problem is in the where clause for the update; I need to apply
> _in(inner_stmt) to something column-like, and I'm missing what that
> would be.  I've tried
> sqlalchemy.sql.expression.ColumnCollection(foo.c.svrid,
> foo.c.asof).in_(inner_stmt) and clearly ColumnCollection has a limited
> set of supported operations.

we have an 0.6 construct called tuple() that allows this.

http://www.sqlalchemy.org/docs/reference/sqlalchemy/expressions.html?highlight=tuple#sqlalchemy.sql.expression.tuple_



>
> Suggestions?
>
> Richard
>
> --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] using in_ against multiple columns

2010-03-16 Thread richard reitmeyer
Hello, all.

I'm trying to use compound fields with in_ to achieve something like
this:

update foo set svrid = NULL, asof=NULL
where (svrid,asof)
  in (select svrid, asof from foo except select svrid,
asof from bar);

Use case is cleaning up entries in foo records that refer to damaged
or missing bar records, where the check is against a column pair. I'm
expecting ~99% of the records in foo to have a correspondence to
something in bar.

My problem is in the where clause for the update; I need to apply
_in(inner_stmt) to something column-like, and I'm missing what that
would be.  I've tried
sqlalchemy.sql.expression.ColumnCollection(foo.c.svrid,
foo.c.asof).in_(inner_stmt) and clearly ColumnCollection has a limited
set of supported operations.

Suggestions?

Richard

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.