Re: [sqlalchemy] further restricting a query provided as raw sql

2010-05-04 Thread Chris Withers

Michael Bayer wrote:

Are the innards of in_ exposed anywhere for public consumption or should
I avoid?


from sqlalchemy.sql import column

column(anything_you_want).in_(['a', 'b', 'c'])


Thanks, that's exactly what I was looking for...

Chris

--
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] filter by backref field

2010-05-04 Thread a...@vurve.com
Hi All,

This might be a noob question, but I wasn't able to to find the answer
combing through the docs and google search.  Given the following
declarations

Base = declarative_base()

class A(Base):
__tablename__ = 'A'
id = Column(Integer, primary_key=True)

class B(Base):
__tablename__ = 'B'
id = Column(Integer, primary_key=True)
a_id = Column(Integer, ForeignKey('A.id'))
a = relationship('A', backref=backref('b'))

I want to query for all A where B is not null (essentially an inner
join on A) with something like this

session.query(A).options(joinedload('b')).filter(A.b != None)

but it won't work because 'A.b' is a backref field.  If I try
filter('A.b' != None) it won't work either.So 2 part question:

1) is there a better way to do an inner join like this?
2) in general, how do you use backref fields inside of filter
criteria?

Thanks,
Alan

-- 
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] filter by backref field

2010-05-04 Thread Conor
On 05/03/2010 10:33 PM, a...@vurve.com wrote:
 Hi All,

 This might be a noob question, but I wasn't able to to find the answer
 combing through the docs and google search.  Given the following
 declarations

 Base = declarative_base()

 class A(Base):
 __tablename__ = 'A'
 id = Column(Integer, primary_key=True)

 class B(Base):
 __tablename__ = 'B'
 id = Column(Integer, primary_key=True)
 a_id = Column(Integer, ForeignKey('A.id'))
 a = relationship('A', backref=backref('b'))

 I want to query for all A where B is not null (essentially an inner
 join on A) with something like this

 session.query(A).options(joinedload('b')).filter(A.b != None)

 but it won't work because 'A.b' is a backref field.  If I try
 filter('A.b' != None) it won't work either.So 2 part question:

 1) is there a better way to do an inner join like this?
 2) in general, how do you use backref fields inside of filter
 criteria?

   

The problem is not due to the backref: it is because A.b is a
one-to-many relationship, and A.b != None does not make sense for a
one-to-many relationship. If you really want inner-join semantics, then
you can do this (note that no filter is needed because that is
inherently part of the inner join):

session.query(A).join(A.b).options(contains_eager('b'))

Alternatively, if you want to ensure that the database returns only one
row per A, you can use a query like this, which will use an EXISTS clause:

session.query(A).filter(A.b.any())

Note that the query object will filter out duplicate As on the client
side in any case, so you will not notice a difference between these queries.

-Conor

-- 
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: reflecting (autoload=True) MySQL tinyint(1) fields

2010-05-04 Thread Brad Wells
The docs for the MySQL dialect need to be updated to reflect this
change. See 
http://www.sqlalchemy.org/docs/reference/dialects/mysql.html#sqlalchemy.dialects.mysql.TINYINT

For what it's worth I'd really like to see this remain as an optional
behavior. The BOOL/BOOLEN column types in MySQL are synonyms for
TINYINT(1). Someone creating columns using BOOLs might reasonably
expect to reflect that intention when autoloading. Really though, I
just want a way to avoid manually overriding 200 column definitions.
Is there a reasonable way to do that as is?


On Mar 27, 5:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Mar 27, 2010, at 5:17 PM, Michael Bayer wrote:





  On Mar 27, 2010, at 4:16 PM, Lloyd Kvam wrote:

  I've just discovered that some tinyint (8-bit) fields have had their
  values limited to 0 and 1 regardless of actual value supplied.  Digging
  through the documentation, I've learned that when MySQL tables are
  reflected, tinyint(1) fields are processed as booleans.

  I did not find emails from others howling in pain, so I suppose most
  people are either happy with this behavior or unaffected.  I understand
  why a bool column definition would be mapped to tinyint(1).  However,
  doing the reverse, mapping tinyint(1) to bool, discards bits that MySQL
  would not discard.

  For me this was a misfeature.  I would think that supplying bools to an
  integer field would work OK.  In python 2 + True == 3.  So people using
  booleans should not have too much difficulty, would they?  Is there any
  chance you'd consider autoloading tinyint(1) as an integer field?

  sure i will remove this behavior today.

 it is out in r95ac46ca88ee.



  --
  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 
  athttp://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 
  athttp://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] session lifecycle and wsgi

2010-05-04 Thread Chris Withers

Michael Bayer wrote:


(I'm guessing session.merge will whine if handed an object that is 
already in another session?)


mm no merge() leaves the original unaffected.  it copies state to an 
instance internal to the session.   this is very clear here: 
 http://www.sqlalchemy.org/docs/session.html#merging


Gotcha.

So putting non-expunged objects in something like a beaker cache would 
be a no-no, correct? (would .close() or .remove() fix the problem if 
the objects are already in the cache by the time the .close() or 
.remove() is called?)


in most cases its actually fine.file, memcached, reldb, dbm backends 
all serialize the given object, which means you're only storing a copy. 
   If the cache is storing things locally to the current session (see 
examples/beaker_cache/local_session_caching.py), then you dont want to 
expunge the object since you'd like it to be in the session at the same 
time.  only in-memory, non-session-scoped caches have this limitation, 
such as if you were using a memory backend with beaker.


OK, thanks. Where can I find good examples of the various ways Beaker 
can be used with a multi-threaded wsgi app?


Does the ORM check if the attributes of the cached object are correct 
or would you end up in a situation where you do a query but end up 
using the cached attributes rather than the ones just returned from 
the db?


that all depends how you get the object from a cache back into your 
session.usually not since having to hit the DB to verify attributes 
defeats the purpose of a cache.   pretty much only if you used merge() 
with load=True.


I wasn't quite clear, let me try again. So, I've merged an object with 
load=False. I then do a session.query(ThatObjectsClass).all() which 
should include that object. Will the object have the correct attributes 
or the stale cached ones?


- They don't explain what happens to transactions and connections. The 
points for both remove() and close() say all of its 
transactional/connection resources are closed out; does this mean 
database connections or closed or just returned to the pool? (I hope 
the latter!)


closed out means rolled back and returned to thoe pool.



- The point for .commit() states The full state of the session is 
expired, so that when the next web request is started, all data will 
be reloaded but your last reply implied this wouldn't always be the case.


The instantiated objects that are in the session still stay around as 
long as they are referenced externally.  but all their attributes are 
gone, as well as the new and deleted collections are empty.   so all 
data will be reloaded.




Also, is it fair game to assume that session.close() rolls back any 
open database transaction? Is there any difference between that 
rollback and calling session.rollback() explicitly?


i think the rollback which close() might get to the point more directly 
internallybut from a connection point of view there's no different.


Thanks for the clarification :-)

Finally, in nosing around session.py, I notice that 
SessionTransactions can be used as context managers. Where can I find 
good examples of this?


you'd be saying with session.begin():


...and then the session would be committed or rolled back depending on 
whether an exception was raised in the with block or not?


If so, cool :-)

Chris

--
Simplistix - Content Management, Batch Processing  Python Consulting
- http://www.simplistix.co.uk

--
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] session lifecycle and wsgi

2010-05-04 Thread Michael Bayer

On May 4, 2010, at 1:59 PM, Chris Withers wrote:

 So putting non-expunged objects in something like a beaker cache would be a 
 no-no, correct? (would .close() or .remove() fix the problem if the objects 
 are already in the cache by the time the .close() or .remove() is called?)
 in most cases its actually fine.file, memcached, reldb, dbm backends all 
 serialize the given object, which means you're only storing a copy.If 
 the cache is storing things locally to the current session (see 
 examples/beaker_cache/local_session_caching.py), then you dont want to 
 expunge the object since you'd like it to be in the session at the same 
 time.  only in-memory, non-session-scoped caches have this limitation, such 
 as if you were using a memory backend with beaker.
 
 OK, thanks. Where can I find good examples of the various ways Beaker can be 
 used with a multi-threaded wsgi app?

those *are* the examples ...  examples/beaker_cache.   multithreaded doesn't 
change any of the code

 
 Does the ORM check if the attributes of the cached object are correct or 
 would you end up in a situation where you do a query but end up using the 
 cached attributes rather than the ones just returned from the db?
 that all depends how you get the object from a cache back into your session. 
usually not since having to hit the DB to verify attributes defeats the 
 purpose of a cache.   pretty much only if you used merge() with load=True.
 
 I wasn't quite clear, let me try again. So, I've merged an object with 
 load=False. I then do a session.query(ThatObjectsClass).all() which should 
 include that object. Will the object have the correct attributes or the stale 
 cached ones?

it will have whatever you merged in from the outside (yes, the cache).  
merge(load=False) copies the incoming attributes unconditionally.  whatever 
attributes aren't present on the incoming will be loaded from the DB when 
accessed.

 
 - They don't explain what happens to transactions and connections. The 
 points for both remove() and close() say all of its 
 transactional/connection resources are closed out; does this mean database 
 connections or closed or just returned to the pool? (I hope the latter!)
 closed out means rolled back and returned to thoe pool.
 
 - The point for .commit() states The full state of the session is expired, 
 so that when the next web request is started, all data will be reloaded 
 but your last reply implied this wouldn't always be the case.
 The instantiated objects that are in the session still stay around as long 
 as they are referenced externally.  but all their attributes are gone, as 
 well as the new and deleted collections are empty.   so all data will be 
 reloaded.
 
 Also, is it fair game to assume that session.close() rolls back any open 
 database transaction? Is there any difference between that rollback and 
 calling session.rollback() explicitly?
 i think the rollback which close() might get to the point more directly 
 internallybut from a connection point of view there's no different.
 
 Thanks for the clarification :-)
 
 Finally, in nosing around session.py, I notice that SessionTransactions can 
 be used as context managers. Where can I find good examples of this?
 you'd be saying with session.begin():
 
 ...and then the session would be committed or rolled back depending on 
 whether an exception was raised in the with block or not?

well, it wouldn't be very useful if it didn't check for an exception, so yes, 
it does what you'd expect.


-- 
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: reflecting (autoload=True) MySQL tinyint(1) fields

2010-05-04 Thread Michael Bayer

On May 4, 2010, at 1:22 PM, Brad Wells wrote:

 The docs for the MySQL dialect need to be updated to reflect this
 change. See 
 http://www.sqlalchemy.org/docs/reference/dialects/mysql.html#sqlalchemy.dialects.mysql.TINYINT
 
 For what it's worth I'd really like to see this remain as an optional
 behavior. The BOOL/BOOLEN column types in MySQL are synonyms for
 TINYINT(1). Someone creating columns using BOOLs might reasonably
 expect to reflect that intention when autoloading. Really though, I
 just want a way to avoid manually overriding 200 column definitions.
 Is there a reasonable way to do that as is?

if you reflect as TINYINT you still get a 0/1 back in results and it still 
accepts True/False.You really need it to give you the True/ False 
tokens ?

this is not entirely de facto in its methodology but this should work for now:

# before create_engine is called

from sqlalchemy.dialects.mysql import base
base.ischema_names['tinyint'] = base.BOOLEAN



 
 
 On Mar 27, 5:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Mar 27, 2010, at 5:17 PM, Michael Bayer wrote:
 
 
 
 
 
 On Mar 27, 2010, at 4:16 PM, Lloyd Kvam wrote:
 
 I've just discovered that some tinyint (8-bit) fields have had their
 values limited to 0 and 1 regardless of actual value supplied.  Digging
 through the documentation, I've learned that when MySQL tables are
 reflected, tinyint(1) fields are processed as booleans.
 
 I did not find emails from others howling in pain, so I suppose most
 people are either happy with this behavior or unaffected.  I understand
 why a bool column definition would be mapped to tinyint(1).  However,
 doing the reverse, mapping tinyint(1) to bool, discards bits that MySQL
 would not discard.
 
 For me this was a misfeature.  I would think that supplying bools to an
 integer field would work OK.  In python 2 + True == 3.  So people using
 booleans should not have too much difficulty, would they?  Is there any
 chance you'd consider autoloading tinyint(1) as an integer field?
 
 sure i will remove this behavior today.
 
 it is out in r95ac46ca88ee.
 
 
 
 --
 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 
 athttp://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 
 athttp://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.
 

-- 
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] disable RETURNING for specific primary key columns

2010-05-04 Thread Kent
I understand I can disable RETURNING for an engine with
'implicit_returning=False'

Is there a way to do this for certain primary key columns only, but
not disabled engine-wide?

(We've done some flexible view creation so that our app (sqlalchemy)
sees the same database metadata whether we are on a legacy oracle
system or a postgres database.  In some cases the 'tables' are views
that don't support RETURNING, so I'd like to turn it off for those
cases only...)

Kent

-- 
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] disable RETURNING for specific primary key columns

2010-05-04 Thread Michael Bayer

On May 4, 2010, at 2:30 PM, Kent wrote:

 I understand I can disable RETURNING for an engine with
 'implicit_returning=False'
 
 Is there a way to do this for certain primary key columns only, but
 not disabled engine-wide?
 
 (We've done some flexible view creation so that our app (sqlalchemy)
 sees the same database metadata whether we are on a legacy oracle
 system or a postgres database.  In some cases the 'tables' are views
 that don't support RETURNING, so I'd like to turn it off for those
 cases only...)

Table() accepts it as a keyword argument as well.


-- 
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] disable RETURNING for specific primary key columns

2010-05-04 Thread Kent Bower

You think of everything? ;)  Thanks

On 5/4/2010 2:41 PM, Michael Bayer wrote:

On May 4, 2010, at 2:30 PM, Kent wrote:

   

I understand I can disable RETURNING for an engine with
'implicit_returning=False'

Is there a way to do this for certain primary key columns only, but
not disabled engine-wide?

(We've done some flexible view creation so that our app (sqlalchemy)
sees the same database metadata whether we are on a legacy oracle
system or a postgres database.  In some cases the 'tables' are views
that don't support RETURNING, so I'd like to turn it off for those
cases only...)
 

Table() accepts it as a keyword argument as well.


   


--
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] disable RETURNING for specific primary key columns

2010-05-04 Thread Michael Bayer
we needed it foroh MS-SQL tables that have triggers.   

On May 4, 2010, at 3:11 PM, Kent Bower wrote:

 You think of everything? ;)  Thanks
 
 On 5/4/2010 2:41 PM, Michael Bayer wrote:
 On May 4, 2010, at 2:30 PM, Kent wrote:
 
   
 I understand I can disable RETURNING for an engine with
 'implicit_returning=False'
 
 Is there a way to do this for certain primary key columns only, but
 not disabled engine-wide?
 
 (We've done some flexible view creation so that our app (sqlalchemy)
 sees the same database metadata whether we are on a legacy oracle
 system or a postgres database.  In some cases the 'tables' are views
 that don't support RETURNING, so I'd like to turn it off for those
 cases only...)
 
 Table() accepts it as a keyword argument as well.
 
 
   
 
 -- 
 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] Re: reflecting (autoload=True) MySQL tinyint(1) fields

2010-05-04 Thread Brad Wells
0/1 generally works in Python but won't convert to formats with native
boolean values correctly, in my case JSON.

Just a note, your suggestion works for me but will fail for any
unsigned columns.

I have a working solution so I'm fine with moving on from the issue,
Overall however, with MySQL's lack of a true boolean data type this
change leaves MySQL users with no particularly clean way to represent
true boolean types. Just my two cents.

Thanks for the help.

On May 4, 2:06 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On May 4, 2010, at 1:22 PM, Brad Wells wrote:

  The docs for the MySQL dialect need to be updated to reflect this
  change. 
  Seehttp://www.sqlalchemy.org/docs/reference/dialects/mysql.html#sqlalche...

  For what it's worth I'd really like to see this remain as an optional
  behavior. The BOOL/BOOLEN column types in MySQL are synonyms for
  TINYINT(1). Someone creating columns using BOOLs might reasonably
  expect to reflect that intention when autoloading. Really though, I
  just want a way to avoid manually overriding 200 column definitions.
  Is there a reasonable way to do that as is?

 if you reflect as TINYINT you still get a 0/1 back in results and it still 
 accepts True/False.    You really need it to give you the True/ False 
 tokens ?

 this is not entirely de facto in its methodology but this should work for 
 now:

 # before create_engine is called

 from sqlalchemy.dialects.mysql import base
 base.ischema_names['tinyint'] = base.BOOLEAN





  On Mar 27, 5:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  On Mar 27, 2010, at 5:17 PM, Michael Bayer wrote:

  On Mar 27, 2010, at 4:16 PM, Lloyd Kvam wrote:

  I've just discovered that some tinyint (8-bit) fields have had their
  values limited to 0 and 1 regardless of actual value supplied.  Digging
  through the documentation, I've learned that when MySQL tables are
  reflected, tinyint(1) fields are processed as booleans.

  I did not find emails from others howling in pain, so I suppose most
  people are either happy with this behavior or unaffected.  I understand
  why a bool column definition would be mapped to tinyint(1).  However,
  doing the reverse, mapping tinyint(1) to bool, discards bits that MySQL
  would not discard.

  For me this was a misfeature.  I would think that supplying bools to an
  integer field would work OK.  In python 2 + True == 3.  So people using
  booleans should not have too much difficulty, would they?  Is there any
  chance you'd consider autoloading tinyint(1) as an integer field?

  sure i will remove this behavior today.

  it is out in r95ac46ca88ee.

  --
  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 
  athttp://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 
  athttp://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 
  athttp://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 
 athttp://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] Best way to order by columns in relationships?

2010-05-04 Thread Timmy Chan
i have a few polymorphic tables, and i want to sort by a column in one of
the relationship.

i have tables a,b,c,d, with relationship a to b, b to c, c to d.

a to b is one-to-many b to c and c to d are one-to-one, but polymorphic.

given an item in table a, i will have a list of items b, c, d (all one to
one). how do i use sqlalchemy to sort them by a column in table d?

what i want is the sql statement:

select * from b
inner join c on b.c_key = c.b_key
inner join d on c.d_key = d.c_key
where b.a_key = ?
order by d.sort_key

in sqlalchemy.  it does not have to be on one query, as c and d are
polymorphic tables.  i have relationships on each of a, b, c, d. but as c
and d are polymorphic tables (on b), so i cannot hard code it.

-- 
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] Get list of items to be flushed in session extension

2010-05-04 Thread chris e
I'm trying to provide functionality in a session extension  for an
class to provide a 'before_flush' method that allows the class to make
changes to the session, and add additional items. To do this I need to
get the list of instances to be flushed to the database, and the order
in which sqlalchemy would commit the changes to the database. I then
reverse the order of this list so that items that the instances are
processed in the reverse order of the database commits. I used to do
this using some of the internal task functionality of UOW(see below),
but that is no longer available in 0.6.0. Any suggestions?

   # from UOW
while True:
ret = False
for task in uow.tasks.values():
for up in list(task.dependencies):
if up.preexecute(uow):
ret = True
if not ret:
break

# HACK we are using a hidden method of UOW here
# run our tasks in reverse order this will
# cause child flushes to be called before
# parent ones
tasks = uow._sort_dependencies()
tasks.reverse()
reprocess = False
for task in tasks :
for element in task.elements :
obj_instance = element.state.obj()
if hasattr(obj_instance, 'before_flush')
and \
 
callable(obj_instance.before_flush) and \
not obj_instance in
self.before_items_processed :
reprocess = \
obj_instance.before_flush() or
reprocess and True or False
 
self.before_items_processed.append(obj_instance)

if reprocess :
self._before_flush_inner(session, instances_in)

-- 
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] Get list of items to be flushed in session extension

2010-05-04 Thread Michael Bayer

On May 4, 2010, at 5:23 PM, chris e wrote:

 I'm trying to provide functionality in a session extension  for an
 class to provide a 'before_flush' method that allows the class to make
 changes to the session, and add additional items. To do this I need to
 get the list of instances to be flushed to the database, and the order
 in which sqlalchemy would commit the changes to the database. I then
 reverse the order of this list so that items that the instances are
 processed in the reverse order of the database commits. I used to do
 this using some of the internal task functionality of UOW(see below),
 but that is no longer available in 0.6.0. Any suggestions?

getting the order is pretty controversial.what elements of the order 
are significant to you and why isn't this something you are tracking yourself ? 
 wiring business logic onto the details of persistence doesn't seem like a good 
idea.   Or are your flush rules related to SQL -level dependencies, in which 
case why not let the flush handle it, or at least use a MapperExtension so that 
your hooks are invoked within the order of flush  ?

anyway, the order is available in a similar way as before if you peek into 
what UOWTransaction.execute() is calling, namely _generate_actions().It 
would be necessary for you to call this separately yourself which is fairly 
wasteful from a performance standpoint.   it returns a structure that is 
significantly simpler than the old one but you'll still have to poke around 
unitofwork.py to get a feel for it, since this isn't any kind of documented 
public API (you obviously figured out the previous one, this one is simpler).

-- 
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: Get list of items to be flushed in session extension

2010-05-04 Thread chris e
I'll look into the new code. It does look simpler. I tried using the
MapperExtension functionality, but, the last time I tried to use it,
it did not allow for orm level changes(new items added to the session,
or attribute changes) to be made, as the UOW has already been
calculated. My main use case is business logic where child objects end
up updating parent items, or adding items to parent relations. Once
the UOW is calculated I have found that changes to items and their
relations are not caught, which makes sense.

I'd love to have something in the public session/UOW api that provides
the items to be flushed in the order in which they are being flushed,
even though this may be an expensive operation.


On May 4, 4:17 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On May 4, 2010, at 5:23 PM, chris e wrote:

  I'm trying to provide functionality in a session extension  for an
  class to provide a 'before_flush' method that allows the class to make
  changes to the session, and add additional items. To do this I need to
  get the list of instances to be flushed to the database, and the order
  in which sqlalchemy would commit the changes to the database. I then
  reverse the order of this list so that items that the instances are
  processed in the reverse order of the database commits. I used to do
  this using some of the internal task functionality of UOW(see below),
  but that is no longer available in 0.6.0. Any suggestions?

 getting the order is pretty controversial.    what elements of the order 
 are significant to you and why isn't this something you are tracking yourself 
 ?  wiring business logic onto the details of persistence doesn't seem like a 
 good idea.   Or are your flush rules related to SQL -level dependencies, in 
 which case why not let the flush handle it, or at least use a MapperExtension 
 so that your hooks are invoked within the order of flush  ?

 anyway, the order is available in a similar way as before if you peek into 
 what UOWTransaction.execute() is calling, namely _generate_actions().    It 
 would be necessary for you to call this separately yourself which is fairly 
 wasteful from a performance standpoint.   it returns a structure that is 
 significantly simpler than the old one but you'll still have to poke around 
 unitofwork.py to get a feel for it, since this isn't any kind of documented 
 public API (you obviously figured out the previous one, this one is simpler).

 --
 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 
 athttp://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: Get list of items to be flushed in session extension

2010-05-04 Thread Michael Bayer

On May 4, 2010, at 7:42 PM, chris e wrote:

 I'll look into the new code. It does look simpler. I tried using the
 MapperExtension functionality, but, the last time I tried to use it,
 it did not allow for orm level changes(new items added to the session,
 or attribute changes) to be made, as the UOW has already been
 calculated. My main use case is business logic where child objects end
 up updating parent items, or adding items to parent relations. Once
 the UOW is calculated I have found that changes to items and their
 relations are not caught, which makes sense.

yeah what I dont understand is why the order of things persisted matters when 
you're inside of before_flush().the only thing that the sorting inside 
flush determines, which has a visible effect on the ultimate outcome, is the 
order of INSERT for a series of rows in a table.   this is derived from the 
order in which things were add()ed to the session, and is available ahead of 
time off the instance_state.The only time this behavior might be more 
complex is if one or more of the rows of one table are dependent on other rows 
in that table.   everything else about the order of things occuring has to do 
with insert into table B before table A and so forth, nothing you need to 
know if you arent issuing INSERT statements yourself within before_flush().  





 
 I'd love to have something in the public session/UOW api that provides
 the items to be flushed in the order in which they are being flushed,
 even though this may be an expensive operation.
 
 
 On May 4, 4:17 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On May 4, 2010, at 5:23 PM, chris e wrote:
 
 I'm trying to provide functionality in a session extension  for an
 class to provide a 'before_flush' method that allows the class to make
 changes to the session, and add additional items. To do this I need to
 get the list of instances to be flushed to the database, and the order
 in which sqlalchemy would commit the changes to the database. I then
 reverse the order of this list so that items that the instances are
 processed in the reverse order of the database commits. I used to do
 this using some of the internal task functionality of UOW(see below),
 but that is no longer available in 0.6.0. Any suggestions?
 
 getting the order is pretty controversial.what elements of the order 
 are significant to you and why isn't this something you are tracking 
 yourself ?  wiring business logic onto the details of persistence doesn't 
 seem like a good idea.   Or are your flush rules related to SQL -level 
 dependencies, in which case why not let the flush handle it, or at least use 
 a MapperExtension so that your hooks are invoked within the order of flush  ?
 
 anyway, the order is available in a similar way as before if you peek into 
 what UOWTransaction.execute() is calling, namely _generate_actions().It 
 would be necessary for you to call this separately yourself which is fairly 
 wasteful from a performance standpoint.   it returns a structure that is 
 significantly simpler than the old one but you'll still have to poke around 
 unitofwork.py to get a feel for it, since this isn't any kind of documented 
 public API (you obviously figured out the previous one, this one is simpler).
 
 --
 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 
 athttp://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.
 

-- 
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.