こんにちは,ちゆりです。
FlaskとSQLAlchemyでWebアプリを開発しているとDB関連のエラーで悩まされます。SQLAlchemyのブラックボックス感ゆえに解決方法を見出すのに苦労する日々です。。
といいながらもSQLAlchemyの有能さがクセになり,もう手放せないのですが。。。
そして,今回は
sqlalchemy.exc.ArgumentError:
Mapper mapped class classname->tablename
could not assemble any primary key columns for mapped table 'tablename'
のエラーの原因を探っていこうと思う。
(見やすさ重視のため3行に改行しております.)
sqlalchemy.exc.ArgumentErrorとは
AegumentErrorというワードから引数エラーなのはなんとなくわかった。
SQLAlchemy公式ドキュメントによると
sqlalchemy.exc.ArgumentError
無効または矛盾する関数引数が指定されたときに発生します。
通常、構築時にエラーとなります。
ということだが,SQLAlchemyさんの言う矛盾というのがよく分からない。
しかし,構築時にエラーとなりますということで,DBの立ち上げ時(テーブルもろもろ)にエラーとなっているのかと目星を付けた。
SQLAlchemyのDB構築時
僕は,Flask/DjangoとSQLalchemyを使っているのですが,DB立ち上げ時はこのように書いている。
#Userテーブル定義
class User(db.Model):#①
__tablename__ = 'login_user'#②
ID = db.Column(Integer, primary_key=True)#③
E_MAIL = db.Column(String(255), unique=True)#④
PASS_WORD = db.Column(String(255))#⑤
Pythonで書くと①でUserというクラスを保持し
②のテーブル名,③④⑤のカラム名でDB構築を行う。
ちなみにこの書き方では,sqlalchemy.exc.ArgumentErrorは発生しない。
では,sqlalchemy.exc.ArgumentErrorが発生する場合を教えてよ。
sqlalchemy.exc.ArgumentErrorを引き起こす書き方
こう書くと,例のエラーが発生する。
#Food/Drinkテーブル定義
class Food_Drink(db.Model):
__tablename__ = 'food_drink'
FOOD_NAME = db.Column(String(64))
DRINK_NAME = db.Column(String(64))
何が違うねん。
だらだら記事にしてても時間の無駄なので,さっそく解決法の結論に行っちゃいましょう。
解決方法はこれ
要はprimary keyが無いですよということでエラーとなっているのだそう。
DBを扱う上でprimary keyの考え方は重要なのに。凡ミス。
Primary key を付けてみましょう。#Food/Drinkテーブル定義
class Food_Drink(db.Model):
__tablename__ = 'food_drink'
FOOD_NAME = db.Column(String(64), primary_key=True)
DRINK_NAME = db.Column(String(64), primary_key=True)
これで,解決!!
でも良いのですが,僕個人的にはprimary keyを複数カラムに持たせることに違和感がありまして。。。(細かい男だな...)
#Food/Drinkテーブル定義
class Food_Drink(db.Model):
__tablename__ = 'food_drink'
ID = db.Column(Integer, primary_key=True)
FOOD_NAME = db.Column(String(64))
DRINK_NAME = db.Column(String(64))
↑このようにIDを持たせて,これをprimary keyとした。
こっちのほうがスッキリしててかっこいいやん。
sqlalchemy.exc.ArgumentErrorが発生したら
Mapper mapped class classname->tablename
could not assemble any primary key columns for mapped table 'tablename'
上記のようなエラーのときはprimary keyがしっかり付与してあるか見直そう。
ありがとう
★次に読んでほしい記事
コメント