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
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users