SQLAlchemy 继承防止创建基类实例

1 投票
1 回答
795 浏览
提问于 2025-04-18 15:01

我创建了以下模型:

class Person(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(1024), nullable=False)
    email = db.Column(db.String(250), nullable=True, unique=True)
    code = db.Column(db.String(10), nullable=False, unique=True)

有些情况下,一个人会变成系统用户。所以,我有了以下模型:

class User(Person):
    password = db.Column(db.String(1024), nullable=False)

我的问题是,当我尝试通过这样的方法从一个人创建一个用户时:

>>> person = Person(name='foobar', email='foobar@gmail.com', code='123123')
>>> db.session.add(person)
>>> db.session.commit()
>>> print person.id
4
>>> user = User(id=4, password='changeme')
>>> db.session.add(user)
>>> db.session.commit()
(IntegrityError) null value in column "name" violates not-null constraint
'INSERT INTO person (id, name, ....

我想知道怎么才能防止模型用户创建一个新的“人”的实例,因为这个“人”已经在数据库里存在了?


更新: 当我尝试使用表连接继承时,我遇到了同样的问题。我不明白怎么才能不创建一个新的“人”的实例。

class Person(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(1024), nullable=False)
    email = db.Column(db.String(250), nullable=True, unique=True)
    code = db.Column(db.String(10), nullable=False, unique=True)
    person_type = db.Column(db.String(10), nullable=False)


    __mapper_args__ = {'polymorphic_on': 'person_type'}

class User(Person):
    __mapper_args__ = {'polymorphic_identity': 'recurvado'}

    id = db.Column(db.Integer, db.ForeignKey('arco.id'), primary_key=True)
    password = db.Column(db.String(1024), nullable=False)

我的问题是,当我尝试通过这样的方法从一个人创建一个用户时:

>>> person = Person(name='foobar', email='foobar@gmail.com', code='123123')
>>> db.session.add(person)
>>> db.session.commit()
>>> print person.id
4
>>> user = User(id=4, password='changeme')
>>> db.session.add(user)
>>> db.session.commit()
(IntegrityError) null value in column "name" violates not-null constraint
'INSERT INTO person (id, name, .

1 个回答

1

有几种方法可以做到这一点。简单的方法是

class Person(object): #notice there's no db.Model here
    id = db.Column(db.Integer, primary_key=True)
    #the rest of the person columns follow

class User(Person):
    password = db.Column(db.String(1024), nullable=False)
    #other user specific attributes and columns

如果你不想让你的 Person 类被当作数据库对象直接使用,上面的方式就很好。如果你确实想这样做,那你可以看看这个链接:http://docs.sqlalchemy.org/en/rel_0_9/orm/inheritance.html#single-table-inheritance,选择最适合你的方法,文档内容非常丰富。

撰写回答