Flask-SQLAlchemy polymorphic association(烧瓶-SQL炼金术的多态关联)
本文介绍了烧瓶-SQL炼金术的多态关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有两个主表,角色和用户,在用户上,我将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': '*'
}
但我收到此错误消息:
尝试将类型为的项目刷新为集合的成员 "角色用户"。应为类型的对象或多态子类 这种类型的。如果是的子类,请配置映射器"Mapper|User|Users" 要以多态方式加载此子类型,或将ENABLE_TYPEECECKS设置为FALSE 若要允许接受任何子类型进行刷新,请执行以下操作。
我尝试在角色表的用户字段上设置enable_typechecks=False
,然后收到此错误消息:
opcopg2.errors.UniqueViolation)重复的键值违反唯一性 约束"ix_Users_Email"详细信息:密钥 (电子邮件)=(zidanecr7kaka2@gmail.com)已经存在。[SQL:‘插入到 用户(已确认、名字、姓氏、电子邮件、密码散列 Role_id、Date_of_Birth、Address、Created_at、Update_at)值 (%(已确认)s,%(名字)s,%(姓氏)s,%(电子邮件)s, %(密码散列)s、%(角色id)s、%(出生日期)s、%(地址)s CURRENT_TIMESTAMP,Current_TIMESTAMP)返回users.id‘] [参数:{‘确认’:FALSE,‘FIRST_NAME’:‘tri’,‘LAST_NAME’: ‘nanda’,‘email’:‘zidanecr7kaka2@gmail.com’,‘password_hash’: ‘pbkdf2:sha1:1000$PtpuVYh4$b5bbb03939cf6ca9013308b62276889d35a8cc1b’, ‘Role_id’:5,‘Date_of_Birth’:None,‘Address’:None}]
即使我尝试使用不同的数据,也会收到该消息,但它仍然显示为重复键值。
请告诉我,我的代码..?或任何大小写类似的示例..?
有什么问题吗?推荐答案
找出差异:)
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.polyic_on参数进行了配置。此列将存储一个值,该值指示行中表示的对象类型。该列可以是任何数据类型,但最常用的是字符串和整数。 虽然多态鉴别器表达式不是严格必需的,但如果需要多态加载,则需要该表达式。在基表上建立一个简单的列是实现这一点的最简单方法,但是非常复杂的继承映射甚至可以将SQL表达式(如CASE语句)配置为多态鉴别器。
他们还在教程中建议您不要在子级中使用单独的id列,而将子级id列同时作为主键和外键返回基键。
您可能希望删除";with_polyic";:";*";,因为它会预先加载所有子字段(效率较低)。在某些情况下,您可能需要在执行筛选时启用此功能,但您可以在执行查询时将其打开:https://docs.sqlalchemy.org/en/13/orm/inheritance_loading.html
这篇关于烧瓶-SQL炼金术的多态关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:烧瓶-SQL炼金术的多态关联


猜你喜欢
- padding='same' 转换为 PyTorch padding=# 2022-01-01
- 分析异常:路径不存在:dbfs:/databricks/python/lib/python3.7/site-packages/sampleFolder/data; 2022-01-01
- 沿轴计算直方图 2022-01-01
- 使用Heroku上托管的Selenium登录Instagram时,找不到元素';用户名'; 2022-01-01
- 如何将一个类的函数分成多个文件? 2022-01-01
- pytorch 中的自适应池是如何工作的? 2022-07-12
- 如何在 Python 的元组列表中对每个元组中的第一个值求和? 2022-01-01
- python check_output 失败,退出状态为 1,但 Popen 适用于相同的命令 2022-01-01
- 如何在 python3 中将 OrderedDict 转换为常规字典 2022-01-01
- python-m http.server 443--使用SSL? 2022-01-01