自动创建相关模型

时间:2014-09-07 23:42:42

标签: python sqlalchemy

使用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"不适用,因为文档明确指出不允许添加新实例或修改当前实例。

有没有更好的方法来实现这一目标?

1 个答案:

答案 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))保存实例时,这仍然无法正常工作,但会覆盖大多数其他情况。

至于现在,我没有看到更好的方法。