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

Mic*_*lov 35 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'
Run Code Online (Sandbox Code Playgroud)

我的模特:

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")
Run Code Online (Sandbox Code Playgroud)

Mar*_*ery 32

因为你有你的后尾随逗号你得到这个错误Column()的定义,这导致application_essay_idtheme_essay_id每一个被解析为包含一个元素的元组Column,而不是仅仅一个Column.这会阻止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),
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

然后你的错误将被修复.

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

  • developers_caught_by_this + = 1 (4认同)

Min*_*ham 31

表中不能有两个主键.相反,您必须使用复合主键.这可以通过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")
Run Code Online (Sandbox Code Playgroud)

  • 表中可以有两个主键!参考:http://docs.sqlalchemy.org/en/rel_1_0/orm/extensions/associationproxy.html#simplifying-association-objects (11认同)
  • -1这是胡说八道.在SQLAlchemy模型中有两列带有`primary_key = True`的列是完全合法的(尽管@ChrisJohnson指出,这会创建一个复合主键,而不是"两个主键"),这不是导致错误的原因. (8认同)
  • @karantan,不,你不能在表中有两个主键 - 根据定义,这是不可能的.该doco页面显示的是,您可以在单个主键中包含多个*列*.在某些DBMS中,您还可以声明其他"UNIQUE KEY"约束,这些约束具有主键的许多属性,但根据定义,而不是"主要". (5认同)
  • 您可以声明多个列作为主键,sqlalchemy 会将其转换为复合键 (3认同)

小智 25

尽管上面已经给出了很好的答案,但人们可能犯的一个小错误是创建一个没有任何主键的表。尽管看起来没有必要,但实际上需要为每个表创建主键。否则会抛出上面的错误。