使用SQLAlchemy我有一个1-1的关系:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
class UserProfile(Base):
__tablename__ = 'user_profiles'
user_id = Column(Integer, ForeignKey(User.id), primary_key=True)
user = relationship(User,
backref=backref('profile', uselist=False),
foreign_keys=did)
要求每个User
始终都有关联的UserProfile
,即使是这样创建的:
user = User()
session.add(user)
session.commit(user)
有没有办法自动创建和关联相关实体?
目前,我这样做:
@event.listens_for(User, 'init')
def on_user_init(target, args, kwargs):
if not target.profile:
target.profile = UserProfile()
然而,这有时会导致
IntegrityError:(IntegrityError)重复键值违反唯一 约束" user_profile_pkey" DETAIL:Key(user_id)=(1)已经 存在。 ' INSERT INTO user_profiles ...
因为UserProfile
已分配给已存在的用户。
ORM事件"before_insert"不适用,因为文档明确指出不允许添加新实例或修改当前实例。
有没有更好的方法来实现这一目标?
答案 0 :(得分:1)
快速简便的方法是使用" init" event,但过滤掉具有主键的实例。请注意,在实例初始化时,它是空的,kwargs
参数包含SqlAlchemy(或您的代码)将在其上设置的字段:
@event.listens_for(User, 'init')
def on_user_init(target, args, kwargs):
if not target.profile and 'id' not in kwargs:
target.profile = UserProfile()
当您手动设置id
(例如User(id=1)
)保存实例时,这仍然无法正常工作,但会覆盖大多数其他情况。
至于现在,我没有看到更好的方法。