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

Reply via email to