Python 无法为映射表组装任何主键列
当我尝试创建数据库模式迁移时,我遇到了一个奇怪的错误。你能帮我弄清楚出了什么问题吗Python 无法为映射表组装任何主键列,python,sqlalchemy,flask-sqlalchemy,flask-migrate,Python,Sqlalchemy,Flask Sqlalchemy,Flask Migrate,当我尝试创建数据库模式迁移时,我遇到了一个奇怪的错误。你能帮我弄清楚出了什么问题吗 $ 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' 我的型
$ 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")
表中不能有两个主键。相反,必须使用复合主键。 这可以通过如下方式在模型中添加一个
PrimaryKeyConstraint
来实现(记住在\u table\u args\u\u关闭括号之前添加一个逗号):
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")
出现此错误是因为在Column()
定义后有尾随逗号,这会导致application\u-assessment\u-id
和theme\u-assessment\u-id
被解析为一个包含列而非列的单元素元组。这会阻止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),
与
然后您的错误将被修复
旁白:由于SQLAlchemy(以及Alembic和Flask SQLAlchemy)包含一些用于声明模型/表的语法,这些模型/表涉及将以逗号分隔的列
s序列作为参数传递(例如toop.create_table()
或table()
构造函数)还有一些涉及将列
声明为类属性的类,通过将列
声明从第一个语法剪切和粘贴到第二个语法,并忘记删除一些逗号,很容易出现这种错误。我怀疑这一容易犯的错误是这个问题有如此大的错误的原因ge视图数-在我发布此答案时超过16000个。我之所以出现此错误是因为语法错误。I.v在我的声明中拼错了“primary_key”在关系数据库表中,它必须需要候选键。您可以参考本文
您只需添加主键或复合主键。对于复合主键,您可以在Flask应用程序中使用下一行。无需导入任何内容。所有内容都将由Flask中的db变量进行处理
以你为例,
db.PrimaryKeyConstraint(application_essay_id , application_essay_id )
一个表中可以有两个主键!ref:@karantan,不,一个表中不能有两个主键——从定义上来说,这是不可能的。doco页面显示的是,一个主键中可以有多个列。在某些DBMS中,您还可以声明附加的唯一键
约束,这些约束具有prima的许多属性ry键,但根据定义,不是“主键”。-1这是胡说八道。在SQLAlchemy模型中,两列的primary\u key=True
是完全合法的(尽管@ChrisJohnson指出,这会创建一个复合主键,而不是“两个主键”)这并不是这里错误的原因。唉,如果我这样做,我没有得到正确的设置,相反,我得到了所需的两列组合唯一索引,但每列上也有单独的唯一约束,这会破坏一切。还不清楚为什么。你可以将多列声明为主键,sqlalchemy会将其转换为compound keydevelopers\u抓住了\u this+=1谢谢你的回答-这不仅是正确的,一年后我也遇到了同样的问题:)我忘记添加属性名-(应用程序\u文章id=
部分)由于复制粘贴主键=False
vs True…:/这些小事情会让你花很多时间去发现…:如果其他人犯了我犯过的同样令人愤怒的错误,那么如果在创建列时使用:
而不是=
(就像在pydantic模型中一样),也会出现此错误。
db.PrimaryKeyConstraint(application_essay_id , application_essay_id )