データベーススキーマの移行を作成しようとすると、この奇妙なエラーが発生します。何が悪いのかを理解するのを手伝ってくれませんか?
$ 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")
テーブルに2つの主キーを含めることはできません。代わりに、複合主キーを使用する必要があります。これは、以下のようにモデルに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")
このエラーが発生するのは、Column()
定義の後にコンマがあり、_application_essay_id
_および_theme_essay_id
_が、Column
だけではなく、Column
を含む1要素のタプルとして解析されるためです。 。これにより、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),
_
と
_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)には、Column
sのコンマ区切りのシーケンスを引数として渡すことを含むモデル/テーブルを宣言するための構文が含まれているため(たとえば、op.create_table()
またはTable()
コンストラクターに) )およびクラスのプロパティとしてColumn
sを使用してクラスを宣言することを含むその他の場合、最初の構文から2番目の構文にColumn
宣言をカットアンドペーストし、コンマの一部を削除するのを忘れることで、このエラーが発生しますreally easy 。この簡単な間違いが、この質問が非常に多くのビューを持っている理由だと思います。この回答を投稿した時点では、16000を超えています。