[sqlalchemy] Re: moving an object

2009-04-18 Thread jean-philippe dutreve

Hi, any chance to have a fix for this?

On 6 avr, 17:16, Michael Bayer mike...@zzzcomputing.com wrote:
 OK in fact this can possibly be implemented if the initiator passed
 during attribute mutation operations consisted of not just an
 AttributeImpl but also a target instance, so that append/remove/set
 operations can have the information they need continue down the chain of
 events without exiting prematurely.  Such as this test below:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

 class Parent(Base):
 __tablename__ = 'parent'

 id = Column(Integer, primary_key=True)
 stuff = relation(Stuff, backref=parent)

 class Stuff(Base):
 __tablename__ = 'stuff'

 id = Column(Integer, primary_key=True)
 parent_id = Column(Integer, ForeignKey('parent.id'))

 p1 = Parent()
 p2 = Parent()
 s1 = Stuff()

 p1.stuff.append(s1)
 p2.stuff.append(s1)
 assert s1.parent is p2
 assert s1 not in p1.stuff
 assert s1 in p2.stuff

 can be made to pass if we say this:

 Index: lib/sqlalchemy/orm/attributes.py
 ===
 --- lib/sqlalchemy/orm/attributes.py(revision 5901)
 +++ lib/sqlalchemy/orm/attributes.py(working copy)
 @@ -679,9 +679,6 @@
  collection.append_with_event(value, initiator)

  def remove(self, state, value, initiator, passive=PASSIVE_OFF):
 -if initiator is self:
 -return
 -
  collection = self.get_collection(state, passive=passive)
  if collection is PASSIVE_NORESULT:
  self.fire_remove_event(state, value, initiator)

 so some more complete way of not exiting the event loop too soon would
 need to be implemented.

 Jason, any comments on this ?

 jean-philippe dutreve wrote:

  It would be fine/safe that accountA has entry removed BEFORE any
  reload (with explicit refresh/expire/commit). I can't remember, but a
  previous version of SA had this behavior.

  On Apr 6, 4:42 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  im slightly confused.  the backref should be automatically reparenting,
  not sure if ordering_list interferes with that, but in any case after
  you
  flush()/expire() or commit(), it will definitely happen since all
  collections will load fresh.

  Mike Conley wrote:
   So, we would like SA to have some kind of operation like
  reparent_item()
   that would move anobjectfrom one relation to another.
   It seems to me that this is is better handled as a piece of
  application
   business logic. In this case, provide a move_entry() function that
   properly encapsulates inserting and removing the entry in a single
   operation. I can imagine that there would be many variations on
  business
   rules formovingan item that would be difficult to encapsulate in a
   common
   operation within SA.

   --
   Mike Conley

   On Mon, Apr 6, 2009 at 2:10 AM, jean-philippe dutreve
   jdutr...@gmail.comwrote:

   Currently, I use accountA.remove(entry) and I have rewritten insort
  to
   bypass the bug you say.

   So, AFAIK, whereas an entry has only one account (via
   entry.account_id), SA can't remove the first relation.
   It's dangerous, because if developer forget to remove the first
   relation, the entry is contained in 2 accounts temporaly.
   It can lead to false computation (when summing balance for instance).

   On 5 avr, 22:03, jason kirtland j...@discorporate.us wrote:
jean-philippe dutreve wrote:
 Hi all,

 I wonder if SA can handle this use case:

 An Account can contain Entries ordered by 'position' attribute.

 mapper(Account, table_accounts, properties = dict(
 entries = relation(Entry, lazy=True,
   collection_class=ordering_list
 ('position'),
 order_by=[table_entries.c.position],
 passive_deletes='all', cascade='save-update',
 backref=backref('account', lazy=False),
 ),
 ))

 I'd like to move an entry from accountA to accountB and let SA
   remove
 the link between the entry and accountA:

 entry = accountA.entries[0]
 insort_right(accountB.entries, entry)
 assert not entry in accountA.entries# false, entry is
  still
   in
 accountA 

 It is possible?

Try removing the entry from accountA:

 entry = accountA.pop(0)
 ...

Also beware that bisect insort has a bug that prevents it from
  working
properly with list subclasses like ordering_list (or any SA
  list-based
collection).  I think it's fixed in Python 3.0, not sure if the fix
   was
backported to 2.x.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, 

[sqlalchemy] Eagerloading object/model values

2009-04-18 Thread hticker

I'm quite green with sqlalchemy so please excuse me if this question
is very basic.  I'm having a problem reading property values of an
object after a query.  First let me describe the layout of my
application.  I have a User class which is mapped into a database.
The user class is defined as such:
class User(Base):
__tablename__ = 'users'

id = Column(Integer, primary_key=True)
name = Column(String(40))
hash = Column(String(40))
salt = Column(String(16))


I have a Database class which I use as a wrapper for querying/updating
the database.  Snippet:
class Database:
def __init__(self, file):
self.engine = create_engine('sqlite:///' + file, echo=False)
self.Session = sessionmaker(bind=self.engine)
m = metadata()
m.create_all(self.engine)

def add_user(self,name,passphrase):
#generate a salt for the passphrase and save the hash
#... code excluded
user = User(name,salt,pw_hash)
session = self.Session()
session.add(user)
session.commit()

I ran into a problem when querying the database:
def get_user(self,uname):
session = self.Session()
q = session.query(User).filter_by(name=str(uname)).first()
session.close()
return q

The resulting User object is basically useless as none of its
properties can be accessed (I'm assuming this is because the session
has been closed).  Now leaving the session open is not an option as I
may need to delete the User from another session later.  I believe
what I need is eager loading of all the User properties.  How would
I accomplish this?

thanks,
hticker

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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: moving an object

2009-04-18 Thread Michael Bayer

if we had some help.   the next time I have time to work on SQLAlchemy  
the 0.6 release is my top priority.  this particular issue is a  
behavioral quirk with multiple, straightforward workarounds, and it  
also not entirely clear if continuing event chains in the manner I'm  
proposing is even going to work for all situations - in any case its a  
pretty significant behavioral change.


On Apr 18, 2009, at 5:12 AM, jean-philippe dutreve wrote:


 Hi, any chance to have a fix for this?

 On 6 avr, 17:16, Michael Bayer mike...@zzzcomputing.com wrote:
 OK in fact this can possibly be implemented if the initiator passed
 during attribute mutation operations consisted of not just an
 AttributeImpl but also a target instance, so that append/remove/set
 operations can have the information they need continue down the  
 chain of
 events without exiting prematurely.  Such as this test below:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

 class Parent(Base):
__tablename__ = 'parent'

id = Column(Integer, primary_key=True)
stuff = relation(Stuff, backref=parent)

 class Stuff(Base):
__tablename__ = 'stuff'

id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))

 p1 = Parent()
 p2 = Parent()
 s1 = Stuff()

 p1.stuff.append(s1)
 p2.stuff.append(s1)
 assert s1.parent is p2
 assert s1 not in p1.stuff
 assert s1 in p2.stuff

 can be made to pass if we say this:

 Index: lib/sqlalchemy/orm/attributes.py
 ===
 --- lib/sqlalchemy/orm/attributes.py(revision 5901)
 +++ lib/sqlalchemy/orm/attributes.py(working copy)
 @@ -679,9 +679,6 @@
 collection.append_with_event(value, initiator)

 def remove(self, state, value, initiator, passive=PASSIVE_OFF):
 -if initiator is self:
 -return
 -
 collection = self.get_collection(state, passive=passive)
 if collection is PASSIVE_NORESULT:
 self.fire_remove_event(state, value, initiator)

 so some more complete way of not exiting the event loop too soon  
 would
 need to be implemented.

 Jason, any comments on this ?

 jean-philippe dutreve wrote:

 It would be fine/safe that accountA has entry removed BEFORE any
 reload (with explicit refresh/expire/commit). I can't remember,  
 but a
 previous version of SA had this behavior.

 On Apr 6, 4:42 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 im slightly confused.  the backref should be automatically  
 reparenting,
 not sure if ordering_list interferes with that, but in any case  
 after
 you
 flush()/expire() or commit(), it will definitely happen since all
 collections will load fresh.

 Mike Conley wrote:
 So, we would like SA to have some kind of operation like
 reparent_item()
 that would move anobjectfrom one relation to another.
 It seems to me that this is is better handled as a piece of
 application
 business logic. In this case, provide a move_entry() function  
 that
 properly encapsulates inserting and removing the entry in a single
 operation. I can imagine that there would be many variations on
 business
 rules formovingan item that would be difficult to encapsulate in a
 common
 operation within SA.

 --
 Mike Conley

 On Mon, Apr 6, 2009 at 2:10 AM, jean-philippe dutreve
 jdutr...@gmail.comwrote:

 Currently, I use accountA.remove(entry) and I have rewritten  
 insort
 to
 bypass the bug you say.

 So, AFAIK, whereas an entry has only one account (via
 entry.account_id), SA can't remove the first relation.
 It's dangerous, because if developer forget to remove the first
 relation, the entry is contained in 2 accounts temporaly.
 It can lead to false computation (when summing balance for  
 instance).

 On 5 avr, 22:03, jason kirtland j...@discorporate.us wrote:
 jean-philippe dutreve wrote:
 Hi all,

 I wonder if SA can handle this use case:

 An Account can contain Entries ordered by 'position' attribute.

 mapper(Account, table_accounts, properties = dict(
entries = relation(Entry, lazy=True,
 collection_class=ordering_list
 ('position'),
order_by=[table_entries.c.position],
passive_deletes='all', cascade='save-update',
backref=backref('account', lazy=False),
),
 ))

 I'd like to move an entry from accountA to accountB and let SA
 remove
 the link between the entry and accountA:

entry = accountA.entries[0]
insort_right(accountB.entries, entry)
assert not entry in accountA.entries# false, entry is
 still
 in
 accountA 

 It is possible?

 Try removing the entry from accountA:

 entry = accountA.pop(0)
 ...

 Also beware that bisect insort has a bug that prevents it from
 working
 properly with list subclasses like ordering_list (or any SA
 list-based
 collection).  I think it's fixed in Python 3.0, not sure if  
 the fix
 was
 backported to 2.x.
 



[sqlalchemy] Re: migrating from 0.4 to 0.5

2009-04-18 Thread Michael Bayer


On Apr 17, 2009, at 7:36 PM, dykang wrote:


 Hi,

 I was trying to migrate from 0.4 to 0.5, and I noticed a behavior in
 0.5 that wasn't listed in the migration document that I'd like to
 disable. It appears that in 0.5, begin no longer allows for
 subtransactions by default, and that there is no global flag to turn
 this behavior on.  Is there a recommended strategy for this other than
 search/replace?

 Also, since subtransactions were explicity disabled by default now, is
 there some danger to them that I should be aware of when using them?

the flag was added so that people understand that the begin() they are  
issuing is not a real BEGIN.   they are forced to understand what a  
subtransaction is.

as is typical in python, the two strategies to migrate are search and  
replace, or just a simple monkeypatch on the Session class to get you  
through the day.



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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: migrating from 0.4 to 0.5

2009-04-18 Thread dykang

Thanks for your response.  Would it be unreasonable to request a
global override
for this? Perhaps a sessionmaker option? It feels like it is not
totally unreasonable,
and it helps me prevent a monkey patch or having to type
subtransactions=True every time I call begin. Obviously not a huge
problem, but
just something I'd appreciate.

On Apr 18, 7:59 am, Michael Bayer mike...@zzzcomputing.com wrote:
 On Apr 17, 2009, at 7:36 PM, dykang wrote:



  Hi,

  I was trying to migrate from 0.4 to 0.5, and I noticed a behavior in
  0.5 that wasn't listed in the migration document that I'd like to
  disable. It appears that in 0.5, begin no longer allows for
  subtransactions by default, and that there is no global flag to turn
  this behavior on.  Is there a recommended strategy for this other than
  search/replace?

  Also, since subtransactions were explicity disabled by default now, is
  there some danger to them that I should be aware of when using them?

 the flag was added so that people understand that the begin() they are  
 issuing is not a real BEGIN.   they are forced to understand what a  
 subtransaction is.

 as is typical in python, the two strategies to migrate are search and  
 replace, or just a simple monkeypatch on the Session class to get you  
 through the day.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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
-~--~~~~--~~--~--~---