SQLAlChemy - 模型与表名不同时的外键声明细节 ¶
作者:KK
发表日期:2019.08.14
要点速读: ¶
- 在定义模型关系时,如果被关联模型的名称和它的表名并不完全对应的情况下,外键关联它时要使用它的
__tablename__
属性来获取表名。讲也讲不清楚,还是往下看吧
假设在一个以p_
为表前缀的项目里,有用户表(p_user)和用户组表(p_user_group),对应User和UserGroup模型,定义模型关系时如果两个模型这样写是不对的:
class UserGroup(db.Model):
__tablename__ = 'p_user_group'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String)
users = db.relationship('User', backref = 'user_group', lazy = True)
class User(db.Model):
__tablename__ = 'p_user'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String())
user_group_id = db.Column(db.Integer, db.ForeignKey('UserGroup.id'), nullable = False)
加载时就会发生如下报错:
Could not determine join condition between
parent/child tables on relationship CurriculumVersion.enrollments - there are
no foreign keys linking these tables. Ensure that referencing columns are
associated with a ForeignKey or ForeignKeyConstraint, or specify
a 'primaryjoin' expression.
首先UserGroup的定义代码是没错的,主要是User那里,user_group_id
的关联定义中的UserGroup.id
会被转换成user_group.id
,然后查关联数据时就会往user_group
这张表去查,结果就没这张表。
正确的定义方式应该是利用被关联模型的__tablename__
来拼接:
user_group_id = db.Column(db.Integer, db.ForeignKey(UserGroup.__tablename__ + '.id'), nullable = False)