Python 我如何设置“a”上的属性;“家长”;反对,如果是;“儿童”;对象被指定给一个";关系“;在炼金术中?
当我有两个对象,它们与SQLAlchemy中的“关系”链接时,我意识到简单地分配给该关系不足以将值传播到另一个对象。例如(见下文),如果我有一个“用户”表和一个“联系人”表(两者都是精心设计的,但很好地演示了问题),那么“用户”可以有多个“联系人”。在这种情况下,我将在用户和联系人之间使用外键。如果我创建了Python 我如何设置“a”上的属性;“家长”;反对,如果是;“儿童”;对象被指定给一个";关系“;在炼金术中?,python,sqlalchemy,Python,Sqlalchemy,当我有两个对象,它们与SQLAlchemy中的“关系”链接时,我意识到简单地分配给该关系不足以将值传播到另一个对象。例如(见下文),如果我有一个“用户”表和一个“联系人”表(两者都是精心设计的,但很好地演示了问题),那么“用户”可以有多个“联系人”。在这种情况下,我将在用户和联系人之间使用外键。如果我创建了User和Contact的实例,然后将用户分配给联系人,我希望FK的属性会更新(即使没有数据库刷新),但不会更新。为什么?我如何让SA自动执行此操作 这是我希望能够实现的,但正如您在下面的完整
User
和Contact
的实例,然后将用户分配给联系人,我希望FK的属性会更新(即使没有数据库刷新),但不会更新。为什么?我如何让SA自动执行此操作
这是我希望能够实现的,但正如您在下面的完整示例中所看到的,它没有:
user = User(name='a', lname='b')
contact(type='email', value='foo@bar.com')
contact.user = user
assert contact.username == 'a' # <-- Fails because the attribute is still `None`
user=user(name='a',lname='b')
联系人(type='email',value='2〕foo@bar.com')
contact.user=用户
根据此答案,断言contact.username=='a'#-不可能:
在显式或通过commit()发出flush()之前,不会更新子对象的FK。我认为这样做的原因是,如果关系的父对象也是一个具有自动增量PK的新实例,那么SQLAlchemy需要从数据库中获取PK,然后才能更新子对象上的FK(但我需要更正!)
"""
This code example shows two tables related to each other by a composite key,
using an SQLAlchemy "relation" to allow easy access to related items.
However, as the last few lines show, simply assigning an object A to the
relation of object B does not update the attributes of object B until at least
a "flush" is called.
"""
from sqlalchemy import Column, ForeignKeyConstraint, Unicode, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, sessionmaker
Base = declarative_base()
class User(Base):
__tablename__ = "user"
name = Column(Unicode, primary_key=True)
lname = Column(Unicode, primary_key=True)
class Contact(Base):
__tablename__ = "contact"
__table_args__ = (
ForeignKeyConstraint(
['username', 'userlname'],
['user.name', 'user.lname']
),
)
username = Column(Unicode, primary_key=True)
userlname = Column(Unicode, primary_key=True)
type = Column(Unicode)
value = Column(Unicode)
user = relation(User)
engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
user = User(name="John", lname="Doe")
contact = Contact(type='email', value='john.doe@example.com')
contact.user = user # <-- How can I tell SA to set the FKs on *contact* here?
session.add(contact)
print('Before flush: contact.username user=%r' % contact.username)
session.flush()
print('After flush : contact.username user=%r' % contact.username)