当前位置: 首页 > 知识库问答 >
问题:

炼金术多态关联

韩季
2023-03-14

我有两个主要的表,这是角色和用户,和用户我做3表操作员,教师和学生的关联。

到目前为止,我是这样做的:

class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    permissions = db.Column(db.Integer)
    users = db.relationship('User',
                            backref='role', lazy='dynamic')


class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), index=True)
    email = db.Column(db.String(64), unique=True, index=True)

    password_hash = db.Column(db.String(128))
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    __mapper_args__ = {
        'polymorphic_identity': 'users',
        'with_polymorphic': '*',
    }


class Operator(User):
    __tablename__ = 'operator'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    __mapper_args__ = {
        'polymorphic_identity': 'operator',
        'with_polymorphic': '*'
    }


class Teacher(User):
    __tablename__ = 'teacher'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    phone_number = db.Column(db.Integer)
    other_teacher_data = db.Column(db.String)

    __mapper_args__ = {
        'polymorphic_identity': 'teacher',
        'with_polymorphic': '*'
    }


class Student(User):
    __tablename__ = 'student'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    other_student_data = db.Column(db.String)

    __mapper_args__ = {
        'polymorphic_identity': 'student',
        'with_polymorphic': '*'
    }

但我得到了这个错误信息:

正在尝试将类型为的项刷新为集合“Role.users”的成员。应为类型为的对象或此类型的多态子类。如果是的子类,请配置映射器“mapper | User | users”以多态方式加载此子类型,或设置enable_typechecks=False以允许接受任何子类型进行刷新。

我已尝试在角色表的用户字段上设置启用\u typechecks=False,然后收到以下错误消息:

psycopg2.errors.UniqueViolation)重复键值违反唯一约束“ix_用户\u电子邮件”详细信息:键(电子邮件)=(zidanecr7kaka2@gmail.com)已经存在。[SQL:'在用户(已确认、名、姓、电子邮件、密码散列、角色id、出生日期、地址、创建时间、更新时间)中插入值(%(已确认)s、%(名)、姓、%(电子邮件)s、%(密码散列)s、%(角色id)s、%(出生日期)s、%(地址)s、当前时间戳、当前时间戳)返回用户。id'.[参数:{'confirm':False,'first_name':'Tri','last_name':'Nanda','email':'zidanecr7kaka2@gmail.com“,”密码散列“:”pbkdf2:sha1:1000$PtpuVYh4$b5bbb03939cf6ca9013308b62276889d35a8cc1b”,“角色id”:5,“出生日期”:无,“地址”:无]

即使在尝试使用不同的数据时,我也收到了该消息,但它仍然显示重复的键值。

请问,我的代码有什么问题?或者类似的例子。。?

共有1个答案

贺浩壤
2023-03-14

找出区别:)

from app import db
from flask_login import UserMixin

class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    permissions = db.Column(db.Integer)
    users = db.relationship('User',
                            backref='role', lazy='dynamic')


class User(UserMixin, db.Model): 
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(50))
    name = db.Column(db.String(64), index=True)
    email = db.Column(db.String(64), unique=True, index=True)

    password_hash = db.Column(db.String(128))
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    __mapper_args__ = {
        'polymorphic_identity': 'users',
        'with_polymorphic': '*',
        "polymorphic_on": type
    }


class Operator(User):
    __tablename__ = 'operator'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    __mapper_args__ = {
        'polymorphic_identity': 'operator',
        'with_polymorphic': '*'
    }


class Teacher(User):
    __tablename__ = 'teacher'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    phone_number = db.Column(db.Integer)
    other_teacher_data = db.Column(db.String)

    __mapper_args__ = {
        'polymorphic_identity': 'teacher',
        'with_polymorphic': '*'
    }


class Student(User):  
    __tablename__ = 'student'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    other_student_data = db.Column(db.String)

    __mapper_args__ = {
        'polymorphic_identity': 'student',
        'with_polymorphic': '*'
    }

这不是一条好的错误消息,但是您错过了基类上的type字段。它需要在某个地方存储子表的类型,否则,如果对基类和预期的多态性运行查询,它将不得不搜索所有其他子表以匹配ID。见:

https://docs.sqlalchemy.org/en/13/orm/inheritance.html

上面,建立了一个附加的列类型作为鉴别器,使用mapper.polymorphic_on参数进行配置。此列将存储一个值,该值指示行中表示的对象类型。列可以是任何数据类型,但字符串和整数是最常见的。

虽然多态鉴别器表达式不是严格必需的,但如果需要多态加载,则需要它。在基表上建立一个简单的列是实现这一点的最简单的方法,但是非常复杂的继承映射甚至可以将SQL表达式(如CASE语句)配置为多态鉴别器。

在本教程中,他们还建议不要在子项中使用单独的id列,并将子id列的主键和外键都设置回基键。

您可能需要删除“with_polymopic”:“*”,因为它预先加载所有子字段(效率低下)。在某些情况下,当您执行筛选时,您可能需要此选项,但您可以在执行查询时启用此选项:

https://docs.sqlalchemy.org/en/13/orm/inheritance_loading.html

 类似资料:
  • 这是一个老少皆宜的偏旁造汉字的游戏,锅巴觉得很适合小学生玩,可以帮助他们认字、识字。

  • 假设我有一个模型,其中包含字段和。我想做以下查询: 在SQLAlchemy中,对于单一的一个,这是有效的: 我是否应该添加另一个?或者将和都放在我当前的? 我希望在上优先订购。

  • 我有一个烧瓶应用程序中的表格模型: 我使用和/向上表添加一些数据,效果很好! 然后我想更新和添加一些类文章的属性: 更新类文章后,我再次使用。运行flask应用程序时,收到以下错误消息: 每当我更改子类时,数据库中的表是否会自动同步?子类的属性更改后需要进行什么操作?

  • 我试图执行原始sql查询在我的python应用程序使用heroku数据库.我已经通过运行一个脚本单独创建表 我将数据库配置如下: 当我执行INSERT INTO命令时,我得到一个错误。错误 插入查询:

  • 多态一对多关联 多态关联允许一个模型在单个关联定义方法中从属一个以上其它模型,例如用户可以评论书和文章,但评论表通常都是同一个数据表的设计。多态一对多关联关系,就是为了满足类似的使用场景而设计。 下面是关联表的数据表结构: article id - integer title - string content - text book id - integer

  • 比如我们有一张文章表,一张书籍表,一张标签表,一张标签关联表。文章和书籍共用标签库。 mysql> desc tb_article; +---------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra