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()」を指定したにも関わらず、データがない場合はエラーを吐きますが
本来あるはずのデータがなかった場合にエラーを吐いてくれるのは管理するうえで大きなメリットとなるため
上記のような使い方が推奨されているのだと思います。
以上となります。
ここまで、見ていただき、本当にありがとうございます。
よければ、また遊びに来てください。では。😀
ディスカッション
コメント一覧
まだ、コメントがありません