質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Q&A

解決済

2回答

3575閲覧

MySQL+SQLAlchemyでのrelationalテーブルのdelete

sandalwalk

総合スコア77

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

0グッド

0クリップ

投稿2020/09/26 10:08

料理:カレー
材料:じゃがいも、玉ねぎ、鶏肉

を1つの料理として登録し、
料理のカレーが消去された際には、カレーに関連付けられている材料が全て消去される様にしたいのですが、以下のエラーが出てしまいます。cascade等を具体的にどこにどの様に設定すれば良いでしょうか。
(現在は料理がカレーだけですが、多対多でのリレーションテーブル同士での想定です)

エラー表記 AssertionError: Dependency rule tried to blank-out primary key column 'menu_zairyou_relationtable.zairyou_id' on instance '<MenuZairyou at 0x1091751c0>'

以下が作成したコードです

python3

1class Menu(Base): 2 __tablename__ = 'menu_table' 3 id = Column(Integer,primary_key=True) 4 menu_name = Column(String(100),nullable=False) 5 6 zairyous = relation( 7 'Zairyou', 8 secondary='menu_zairyou_relationtable', 9 cascade='all, delete' 10 ) 11 12 13class Zairyou(Base): 14 __tablename__ = 'zairyou_table' 15 id = Column(Integer,primary_key=True) 16 zairyou_name = Column(String(100),nullable=False) 17 18 menus = relation( 19 'Menu', 20 secondary='menu_zairyou_relationtable', 21 passive_deletes=True 22 ) 23 24 25class MenuZairyou(Base): 26 __tablename__ = 'menu_zairyou_relationtable' 27 28 menu_id = Column(Integer,ForeignKey(Menu.id),primary_key=True) 29 zairyou_id = Column(Integer,ForeignKey(Zairyou.id), primary_key=True) 30 31 menu = relation( 32 'Menu', 33 backref='menu_zairyou_relationtable', 34 cascade="all, delete" 35 ) 36 zairyou = relation( 37 'Zairyou', 38 backref='menu_zairyou_relationtable', 39 cascade="all, delete" 40 ) 41 42def main(): 43 Base.metadata.create_all(engine) 44 SessionMaker = sessionmaker(bind=engine) 45 session = SessionMaker() 46 47 # 初回登録 48 new_menu = Menu(menu_name="カレー") 49 new_zairyou = Zairyou(zairyou_name='じゃがいも') 50 s = MenuZairyou(menu = new_menu, zairyou = new_zairyou) 51 session.add(s) 52 session.commit() 53 54 # カレーの材料を追記 55 new_zairyou = Zairyou(zairyou_name='玉ねぎ') 56 s = MenuZairyou( 57 menu=session.query(Menu).filter(Menu.menu_name=="カレー").first(), 58 zairyou = new_zairyou 59 ) 60 # カレーの材料を追記 61 new_zairyou = Zairyou(zairyou_name='鶏肉') 62 s = MenuZairyou( 63 menu=session.query(Menu).filter(Menu.menu_name=="カレー").first(), 64 zairyou = new_zairyou 65 ) 66 session.add(s) 67 session.commit() 68 69if __name__ == '__main__': 70 main()

上記のコードで登録したテーブルの内容は以下の通りです。

menu_table;
+----+-----------+
| id | menu_name |
+----+-----------+
| 1 | カレー |
+----+-----------+
zairyou_table;
+----+-----------------+
| id | zairyou_name |
+----+-----------------+
| 1 | じゃがいも |
| 2 | 玉ねぎ |
| 3 | 鶏肉 |
+----+-----------------+
menu_zairyou_relationtable;
+---------+------------+
| menu_id | zairyou_id |
+---------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
+---------+------------+

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

  1. まずは素のSQLでのon delete cascadeを指定するCREATE文の書き方を確認しましょう

  2. 次に質問に記載されているコードで作られたテーブルのcreate文を確認しましょう。

show create tableで確認できます。

  1. 1と2が理解出来たら最後にsqlalchemyのon delete cascadeを指定する書き方を見ましょう。こちらはサンプルプログラムで使われているテーブル名もParentChildで書かれているので分かりやすいはずです。

投稿2020/09/26 12:07

hentaiman

総合スコア6415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sandalwalk

2020/09/28 08:39

どうしても上手くいきません。。。他の方法でN:Nの関連付けを試しています。別の質問を投稿しますので、見かけたらコメント頂けると幸いです。
sandalwalk

2020/09/29 07:21

本家の説明がどうしても分かり難かったのですが、併せてYoutubeの解説している方の動画を見た所、本家の説明の意味が少し理解でき、動作しました。本家の説明は理解出来ている人には参考になると思いますが、初学者があれを読んで書けるようにはならないかな。。。という結論です。動作はしていますが、ondelete=, ForeingKey, back_populates, cascade= 等、今回とは異なる条件の場合に使いこなせない気がします。
hentaiman

2020/09/29 08:52

> 初学者があれを読んで書けるようにはならないかな。。。という結論です。 プログラム自体の経験が浅ければ確かにあのドキュメントは読みづらいですね。back_populatesに至ってはDB的には意味分かりませんし。 しかしDBの基本的な部分(cascade等)を知っていれば推測は出来るってところですね。 いきなり多対多で使うのは頭こんがらがりそうなので、まずは普通の親子テーブルでsqlalchemyを利用したon delete cascadeを設定出来るようになってから多対多への応用をするのがいいです。
guest

0

Orale Databaseですが、データの持ち方も含めてFOREIGN KEY 外部キー ON DELETE CASCADE の有無での動作確認 を参考に。

投稿2020/09/26 10:11

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問