【问题标题】:Automatically create related model自动创建相关模型
【发布时间】:2014-09-07 23:42:41
【问题描述】:

使用 SQLAlchemy,我有一对一的关系:

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”详细信息:密钥(user_id)=(1)已经 存在。 'INSERT INTO user_profiles ...

因为UserProfile 分配给了一个已经存在的用户。

ORM 事件"before_insert" 不适用,因为文档明确指出不允许添加新实例或修改当前实例。

有更好的方法来实现吗?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    快速简便的方法是使用“init”事件,但过滤掉具有主键的实例。请注意,在实例初始化时,它是空的,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))保存实例时,这仍然不起作用,但会涵盖大多数其他情况。

    就目前而言,我没有看到更好的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      相关资源
      最近更新 更多