当我尝试创建数据库架构迁移时,我得到了这个奇怪的错误。你能帮我弄清楚是什么错了吗?
$ python app.py db upgrade
[skipped]
sqlalchemy.exc.ArgumentError: Mapper Mapper|EssayStateAssociations|essay_associations could not assemble any primary key columns for mapped table 'essay_associations'
我的模特:
class EssayStateAssociations(db.Model):
__tablename__ = 'essay_associations'
application_essay_id = db.Column(
db.Integer,
db.ForeignKey("application_essay.id"),
primary_key=True),
theme_essay_id = db.Column(
db.Integer,
db.ForeignKey("theme_essay.id"),
primary_key=True),
state = db.Column(db.String, default="pending")
答案 0 :(得分:29)
表中不能有两个主键。相反,您必须使用复合主键。
这可以通过在模型中添加PrimaryKeyConstraint
来完成,如下所示(请记住在__table_args__
中关闭括号之前添加逗号:
from db import PrimaryKeyConstraint
class EssayStateAssociations(db.Model):
__tablename__ = 'essay_associations'
__table_args__ = (
PrimaryKeyConstraint('application_essay_id', 'theme_essay_id'),
)
application_essay_id = db.Column(
db.Integer,
db.ForeignKey("application_essay.id"))
theme_essay_id = db.Column(
db.Integer,
db.ForeignKey("theme_essay.id"))
state = db.Column(db.String, default="pending")
答案 1 :(得分:22)
您收到此错误是因为您的Column()
定义后面有逗号,这导致application_essay_id
和theme_essay_id
每个都被解析为包含{{1}的单元素元组而不仅仅是Column
。这会阻止SQLAlchemy“看到”列存在,从而导致模型不包含任何主键列。
如果您只是替换
Column
与
application_essay_id = db.Column(
db.Integer,
db.ForeignKey("application_essay.id"),
primary_key=True),
theme_essay_id = db.Column(
db.Integer,
db.ForeignKey("theme_essay.id"),
primary_key=True),
然后你的错误将被修复。
除此之外:因为SQLAlchemy(以及Alembic和Flask-SQLAlchemy)包含一些声明模型/表的语法,这些语法/表涉及将逗号分隔的application_essay_id = db.Column(
db.Integer,
db.ForeignKey("application_essay.id"),
primary_key=True)
theme_essay_id = db.Column(
db.Integer,
db.ForeignKey("theme_essay.id"),
primary_key=True)
s序列作为参数传递(例如传递给Column
或者op.create_table()
构造函数)和其他涉及声明具有Table()
s作为类属性的类的其他人,通过剪切和粘贴Column
声明来解决此错误非常容易从第一个语法到第二个,忘记删除一些逗号。我怀疑这个容易犯的错误是这个问题有如此多的观点的原因 - 当我发布这个答案时超过16000个。
答案 2 :(得分:0)
由于语法错误,我收到了此错误。 I.v我的声明中拼错了“ primary_key”
答案 3 :(得分:0)
在关系数据库表中,它必须要求候选键。您可以参考本文https://en.wikipedia.org/wiki/Candidate_key。
您只需要添加主键或复合主键。对于复合主键,可以在Flask APP中使用以下行。无需导入任何东西。一切都会通过Flask中的 db 变量来解决。
在您的示例中,
db.PrimaryKeyConstraint(application_essay_id , application_essay_id )