Python SQLAlchemy:子类模型db条目获取其他子类模型的属性

Python SQLAlchemy:子类模型db条目获取其他子类模型的属性,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我在一个Flask应用程序中遇到了SQLAlchemy的问题,在该应用程序中,我有两个模型讲师和学生,它们是同一个模型用户的子类。当我创建一个学生对象时,它会列在数据库中的“用户”下,其属性对于讲师来说应该是唯一的。以下是我的简化课程: class User(db.Model): __tablename__ = "user" discriminator = db.Column("type", db.String(50)) # Student or Instructor

我在一个Flask应用程序中遇到了SQLAlchemy的问题,在该应用程序中,我有两个模型讲师和学生,它们是同一个模型用户的子类。当我创建一个学生对象时,它会列在数据库中的“用户”下,其属性对于讲师来说应该是唯一的。以下是我的简化课程:

class User(db.Model):
    __tablename__ = "user"
    discriminator = db.Column("type", db.String(50))  # Student or Instructor
    __mapper_args__ = {"polymorphic_on": discriminator}
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50)) 

class Instructor(User):
    __mapper_args__ = {"polymorphic_identity": "instructor"}
    reputation = db.Column(db.Integer, default=1)
    approved_for_teaching = db.Column(db.Boolean, default=False)

class Student(User):
    __mapper_args__ = {"polymorphic_identity": "student"}
    lessons_taken = db.Column(db.Integer, default=0)
我创造了一个这样的学生:

new_student = Student(name=user_name)
db.session.add(new_student)
db.session.commit()

但是,当检查数据库中的对象时,学生从讲师模型中获取属性,即声誉值为1,而approved_for_教学值为False。我在这里做错了什么,还是这是预期的行为?我可以理解这些列是否必须存在,因为它们在数据库中共享同一个表用户,但我希望这些值为null或其他值。谢谢

这是预期行为,因为您正在使用:

单表继承表示单个表中所有子类的所有属性。具有该类特有属性的特定子类将在表中的列中持久化这些属性,如果该行引用其他类型的对象,则这些列为空

尽管文档中提到将属于其他类的列保留为空,但客户端默认在插入到用户表时将列插入,这是从用户继承的所有类的基础,即使它们不是特定子类列的一部分。A也许可以用来避免这种情况,例如:

def polymorphic_default(discriminator, identity, value):
    def default(context):
        # This should be replaced with context.get_current_parameters() in 1.2 and above
        if context.current_parameters[discriminator.name] == identity:
            return value
    return default

...

class Instructor(User):
    __mapper_args__ = {"polymorphic_identity": "instructor"}
    reputation = db.Column(
        db.Integer, default=polymorphic_default(User.discriminator, 'instructor', 1))
    approved_for_teaching = db.Column(
        db.Boolean, default=polymorphic_default(User.discriminator, 'instructor', False))
但要避免一个相当小的问题,这似乎需要做很多工作