Hi Alan - this idea has been mentioned before, and i have a mention about it in the docs (probably should add to the FAQ). basically, if you are playing around with the foreign key identifiers, SA's core ORM has no awareness of that...its interaction with the database is much simpler than that (it tries to be as simple as possible). it has no idea about the meaning of a foreign key identifier until its inside of a flush(). my impression is that it would be a lot more complicated, and add significant latency to attribute operations, for it to reconcile foreign key values as attributes are attached and detached to each other. if we consider the other direction, such as if i say x.user_id=27, and there is no 27 in the identity map..its ambiguous what should happen then. I could do a lazy load (adds latency that might not be desired), or throw an error message. But then, what if you just assigned #27 as the primary key on a transient (unsaved) user object...we arent tracking that either, as transient instances dont have an "identity" until they are flushed. or #27 exists with an identity but it was marked for deletion. There are a lot of complicated conditions that immediately arise, and by keeping tabs on all primary/foreign key values and their status in memory, we're starting to duplicate the functionality of the entire database. as soon as SA is duplicating functionality that is already in the database, thats its primary "red flag" that its going down a path it shouldnt be.
now, if someone were really ambitious, they could create their own attribute plugins to attempt this functionality; it is reasonably straightforward to add event handlers to the attributes created by relation() (just not documented as of yet). if someone wants to get into that, im not opposed; but its definitely something for an extension or external project, since it would complicate and slow down things considerably for it to be built in the core (and also i dont think it would ever work completely the way someone expects). - mike On Aug 22, 2006, at 10:04 AM, Alan Franzoni wrote: > Hello, I've found what I think is an unexpected behaviour in > sqlalchemy; it > has to do with mapped objects and foreign keys handling. Check out > this > snippet: > > #begin > # -*- coding: iso-8859-1 -*- > #main.py > > from sqlalchemy import * > > db = create_engine("sqlite://testdb.db") > > > metadata = BoundMetaData(db) > > users = Table("users", metadata, > Column("user_id", Integer, primary_key=True), > Column("text", String), > ) > > addresses = Table("addresses", metadata, > Column("address_id", Integer, primary_key=True), > Column("user_id", Integer, ForeignKey("users.user_id")) > ) > > users.create(checkfirst=True) > addresses.create(checkfirst=True) > > class User(object): > pass > > class Address(object): > pass > > > def print_user_and_id(obj): > print "user is %s, user_id is %s" % (obj.user, obj.user_id) > > Address.mapper = mapper(Address, addresses) > User.mapper = mapper(User, users, properties = {"addresses": > relation(Address, backref="user")}) > > session = create_session(bind_to=db) > > trans = session.create_transaction() > > user1 = User() > user1.user_id = 10 > user1.text = "Hello World" > > user2 = User() > user2.user_id = 20 > user2.text = "Hello World 2" > > addr1 = Address() > > session.save(user1) > session.save(user2) > session.save(addr1) > > addr1.user_id = user1.user_id > > print_user_and_id(addr1) > > session.flush() > > print_user_and_id(addr1) > > session.refresh(addr1) > > print_user_and_id(addr1) > > addr1.user = user2 > addr1.user_id = 10 > > print_user_and_id(addr1) > > session.flush() > > print_user_and_id(addr1) > #end > > this is the output: > > user is None, user_id is 10 > user is None, user_id is 10 > user is <__main__.User object at 0x00C90030>, user_id is 10 > user is <__main__.User object at 0x00C90050>, user_id is 10 > user is <__main__.User object at 0x00C90050>, user_id is 20 > > > What I think is unexpected is the missing constant 'link' between the > helper property (user), which accepts User objects, and the mapped > property > (user_id), which accepts integers. I would imagine that, if I > changed the > 'user' property, the 'user_id' would immediately reflect that > change, and > viceversa - after all, why not? I can't think of any possible > drawback. > > This way, in order to get the correct values, I need to do a > session.refresh(obj), which can be a bit messy (it's a bit of pain > to do it > again and again). > > Also, the final code snippet is not clear: > > addr1.user = user2 > addr1.user_id = 10 > > In this case, it seems that the 'user' property has priority (when > flushed, > the addr1 object has a user_id of 20), even though the user_id gets > set > later; is it always the case or might this change depending on what > code is > written? > > IMHO the objects should either react immediately to a related property > change, or they shouldn't be both directly accessible, e.g. I > should only > be able to use either user_id or user on an Address object at a > time, not > both. > > -- > Alan Franzoni <[EMAIL PROTECTED]> > - > Togli .xyz dalla mia email per contattarmi. > Rremove .xyz from my address in order to contact me. > - > GPG Key Fingerprint: > 5C77 9DC3 BD5B 3A28 E7BC 921A 0255 42AA FE06 8F3E > - > Blog: http://laterradeglieroi.verdiperronchi.com > > > ---------------------------------------------------------------------- > --- > Using Tomcat but need to do more? Need to support web services, > security? > Get stuff done quickly with pre-integrated technology to make your > job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache > Geronimo > http://sel.as-us.falkag.net/sel? > cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Sqlalchemy-users mailing list > Sqlalchemy-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Sqlalchemy-users mailing list Sqlalchemy-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users