SQLAlchemy データ削除(Dlete)エラーの解決方法【データを1件ずつにすれば解消できる】

こんにちは、説也です。

この記事では、Python + Flask + SQLAlchemyを使用し
DBデータを削除する方法について紹介しています。

データを削除しようとしたら「よくわからないエラーがでてしまった」
という方に向けての記事となります。

少しでも参考になればと思います。

複数のデータを1行で削除しようとするとエラーが発生する

もしかすると、下記のようなメッセージを出してはいませんか?
この原因は削除レコードが分解されていないという理由が多いです。

sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.list’ is not mapped

SQLAlchemyで、1件のレコードを削除する場合下記のような記述をしますよね。

	DleteData = db.session.query(Datatable).filter(Datatable.DataID == DataID).one()
	db.session.delete(DleteData)
	db.session.commit()

エラーが起こるコードは下記のような記述をしたときです。

	DleteData = db.session.query(Datatable).filter(Datatable.DataID == DataID).all()
	db.session.delete(DleteData)
	db.session.commit()

両社の違いは、データレコードが単一か複数かの違いです。

DleteData = db.session.query(Datatable).filter(Datatable.DataID == DataID).one()

DleteData = db.session.query(Datatable).filter(Datatable.DataID == DataID).all()

つまり「.all()」で指定したデータレコードは複数形のデータセットとなるため

データレコードを削除するときに

抽出されてきたデーテレコードのどのレコードを削除するの?という事でエラーを吐きます。

複数のデータセットを削除する方法

メインデータに紐づく、特定IDのデータセットを全て削除したいという場面は多いかと思います。そのような場合は、下記のような記述にすると良いかもしれません。

	DleteDataset = db.session.query(Datatable).filter(Datatable.DataID == DataID).all()
	for DleteData in DleteDataset:
		db.session.delete(DleteData)
		db.session.commit()

まずは、削除したいデータレコードをデータセット(DeleteDataset)に抽出し
そのあとに、データセットを1件ずつ for inループ で削除します。

SQLAlchemyで1件のデータを抽出する方法は2パターンある

SQLAlchemyで1件のデータを抽出する場合、「first()」か「one()」を使用すると思います。

DleteData = db.session.query(Datatable).filter(Datatable.DataID == DataID).first()

DleteData = db.session.query(Datatable).filter(Datatable.DataID == DataID).one()

どちらも、削除を行う場合においては、特に変わりがありませんが、削除するデータが必ずある場合は、「one()」を使用し、削除するデータがない場合もあるときは、「first()」を使用します。

one()」を指定したにも関わらず、データがない場合はエラーを吐きますが
本来あるはずのデータがなかった場合にエラーを吐いてくれるのは管理するうえで大きなメリットとなるため
上記のような使い方が推奨されているのだと思います。

以上となります。

ここまで、見ていただき、本当にありがとうございます。
よければ、また遊びに来てください。では。😀

Pythonをまとめて学びたい方は、まずは無料オンラインセミナーがおすすめ