Python 无法为映射表组装任何主键列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24872541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 05:23:15  来源:igfitidea点击:

Could not assemble any primary key columns for mapped table

pythonsqlalchemyflask-sqlalchemyflask-migrate

提问by Michael Samoylov

When I'm trying to create a database schema migration, I'm getting this weird error. Can you please help me to figure out what's wrong?

当我尝试创建数据库架构迁移时,我收到了这个奇怪的错误。你能帮我弄清楚出了什么问题吗?

$ 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'

My model:

我的型号:

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")

采纳答案by Minh Pham

You cannot have two primary keys in a table. Instead, you must use a compound primary key. This can be done by adding a PrimaryKeyConstraintin your model as below (remember to add a comma before closing the bracket in __table_args__:

一个表中不能有两个主键。相反,您必须使用复合主键。这可以通过PrimaryKeyConstraint在模型中添加 a 来完成,如下所示(记住在关闭括号之前添加逗号__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")

回答by Mark Amery

You get this error because you have trailing commas after your Column()definitions, which cause application_essay_idand theme_essay_idto each be parsed as a one-element tuple containing a Columninstead of just a Column. This stops SQLAlchemy from "seeing" that the columns are present, and consequently causes your model not to contain any primary key column.

之所以会出现此错误,是因为Column()定义后有尾随逗号,这导致application_essay_idtheme_essay_id将每个都解析为包含 aColumn而不仅仅是 a 的单元素元组Column。这会阻止 SQLAlchemy“看到”列存在,从而导致您的模型不包含任何主键列。

If you simply replace

如果你只是更换

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),

with

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)

then your error will be fixed.

那么你的错误将被修复。

Aside: since SQLAlchemy (and Alembic and Flask-SQLAlchemy) contain some syntaxes for declaring models/tables that involve passing a comma-separated sequence of Columns as arguments (e.g. to op.create_table()or the Table()constructor) and others that involve declaring a class with Columns as class properties, it's really easyto run into this error by cutting and pasting Columndeclarations from the first syntax to the second and forgetting to remove some of the commas. I suspect that this easy-to-make mistake is the reason this question has such a huge number of views - over 16000 at the time that I post this answer.

旁白:由于 SQLAlchemy(以及 Alembic 和 Flask-SQLAlchemy)包含一些用于声明模型/表的语法,这些语法涉及将逗号分隔的Columns序列作为参数(例如,toop.create_table()Table()构造函数)和其他涉及将Columns声明为类的类属性,通过将声明从第一个语法剪切并粘贴到第二个语法并忘记删除一些逗号,真的很容易遇到这个错误Column。我怀疑这个容易犯的错误是这个问题有如此多观点的原因——在我发布这个答案时超过 16000。

回答by Valerian Ardelean

I got this error because of a syntax mistake. I.v misspell 'primary_key' in my declaration

由于语法错误,我收到此错误。我在声明中拼错了“primary_key”