Python
MySQL
sqlalchemy
Python3

SQLAlchemy で Delete するには?

More than 1 year has passed since last update.

今回は SQLAlchemyDelete のやり方を書きます。


動作環境


  • Mac OS X 10.11.5

  • Python 3.5.1

  • MySQL Ver 14.14 Distrib 5.7.11, for osx10.11 (x86_64) using EditLine wrapper

  • SQLAlchemy 1.1.0

  • PyMySQL 0.7.4


サンプルコード

まずはシンプルに、テーブルから「name」カラムが "桑田 結子" となっているデータを検索して、削除します。


sqlalchemy_delete.py

# -*- coding:utf-8 -*-

import sqlalchemy
import sqlalchemy.orm
import sqlalchemy.ext.declarative

Base = sqlalchemy.ext.declarative.declarative_base()

class Student(Base):
__tablename__ = 'students'
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
name = sqlalchemy.Column(sqlalchemy.String(20))
kana = sqlalchemy.Column(sqlalchemy.String(40))

def main():
url = 'mysql+pymysql://root:@localhost/test_db?charset=utf8'

engine = sqlalchemy.create_engine(url, echo=False)

# テーブルを作成
Base.metadata.create_all(engine)

# セッションを作成
Session = sqlalchemy.orm.sessionmaker(bind=engine)
session = Session()

# 全データ削除
session.query(Student).delete()

# データベースに追加するデータリスト
student_list = [
Student(id=1, name='石坂 優', kana='いしざか ゆう'),
Student(id=2, name='杉野 誠一', kana='すぎの せいいち'),
Student(id=3, name='桑田 結子', kana='くわた ゆうこ'),
Student(id=4, name='栗原 愛', kana='くりはら あい'),
Student(id=5, name='佐久間 仁', kana='さくま じん'),
]

# データリストを一括追加
session.add_all(student_list)

# 削除対象のデータを検索
found_student = session.query(Student).filter_by(name='桑田 結子').first()

# 指定したデータを削除
session.delete(found_student)

# テーブルの全データを出力
print_all_students(session)

# データベースに反映
session.commit()

# テーブルの全データを出力する関数
def print_all_students(session):
students = session.query(Student).all()
for student in students:
print('%d, %s %s' % (student.id, student.name, student.kana))

if __name__ == '__main__':
main()


次に応用として、フィルタ指定や IN 句指定でデータを削除します。


sqlalchemy_delete.py

# -*- coding:utf-8 -*-

import sqlalchemy
import sqlalchemy.orm
import sqlalchemy.ext.declarative

Base = sqlalchemy.ext.declarative.declarative_base()

class Student(Base):
__tablename__ = 'students'
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
name = sqlalchemy.Column(sqlalchemy.String(20))
kana = sqlalchemy.Column(sqlalchemy.String(40))

def main():
url = 'mysql+pymysql://root:@localhost/test_db?charset=utf8'

engine = sqlalchemy.create_engine(url, echo=False)

# テーブルを作成
Base.metadata.create_all(engine)

# セッションを作成
Session = sqlalchemy.orm.sessionmaker(bind=engine)
session = Session()

# 全データ削除
print("====== session.query(Student).delete() =====")
session.query(Student).delete()
print_all_students(session)

# データベースに追加するデータリスト
student_list = [
Student(id=1, name='石坂 優', kana='いしざか ゆう'),
Student(id=2, name='杉野 誠一', kana='すぎの せいいち'),
Student(id=3, name='桑田 結子', kana='くわた ゆうこ'),
Student(id=4, name='栗原 愛', kana='くりはら あい'),
Student(id=5, name='佐久間 仁', kana='さくま じん'),
]

# データリストを一括追加
print("====== session.add_all(student_list) ======")
session.add_all(student_list)
print_all_students(session)

# フィルタで指定して削除
print("====== session.query(Student).filter(Student.id==2).delete() =====")
session.query(Student).filter(Student.id==2).delete()
print_all_students(session)

# IN 句で指定して削除
print("====== session.query(Student).filter(Student.id.in_([3, 4])).delete(synchronize_session='fetch') =====")
session.query(Student).filter(Student.id.in_([3, 4])).delete(synchronize_session='fetch')
print_all_students(session)

# データベースに反映
session.commit()

# テーブルの全データを出力する関数
def print_all_students(session):
students = session.query(Student).all()
for student in students:
print('%d, %s %s' % (student.id, student.name, student.kana))

if __name__ == '__main__':
main()



まとめ

Session クラスに add_all というメソッドがあるので、全データ削除は delete_all かな?と思われる方もいそうですが、そうではないので注意ですね。

また、delete メソッドの引数 synchronize_session のデフォルト引数は 'evaluate' となっているため、IN 句で指定して削除する場合は 'fetch' を指定しないと例外が発生します。

詳しくは公式ドキュメントを参照してください。

[エラーメッセージ]

sqlalchemy.exc.InvalidRequestError: Could not evaluate current criteria in Python. Specify 'fetch' or False for the synchronize_session parameter.

公式ドキュメント>Query API>delete(synchronize_session='evaluate')

http://docs.sqlalchemy.org/en/rel_1_1/orm/query.html#sqlalchemy.orm.query.Query.delete