概要
PyMySQLドライバを使用してSQL(複数SQL文)を実行したら、以下のエラーになりました。
1064, 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";\nSTART TRANSACTION;\nSET time_zone = "+00:' at line 11'
原因
以前mysqlclientを使っていたときは複数SQL文を正常に実行できていたので、PyMySQLドライバの仕様の問題ではないかと調査。
調査の結果、PyMySQLではデフォルトでcursor.execute()による複数SQL文の実行がサポートされておらず、動作が不安定になることが判明した。
対応
ということで、以下のように修正することで問題解決。
sample.sqlが複数SQL文を実行するファイルとします。
修正前
from django.db import connection
f = open('/etc/sample.sql', 'r')
sql = f.read()
with connection.cursor() as cursor:
cursor.execute(sql) # エラー発生
修正後
from django.db import connection
import subprocess
# subprocess経由でmysql CLIコマンドを使用することで、複数SQL文を正しく処理できる
db_settings = connection.settings_dict
db_name = db_settings['NAME']
db_user = db_settings['USER']
db_password = db_settings['PASSWORD']
db_host = db_settings['HOST']
db_port = db_settings.get('PORT', '3306')
with open('/etc/sample.sql', 'r') as f:
subprocess.run(
['mysql', '-h', db_host, '-P', str(db_port),
'-u', db_user, f'-p{db_password}', db_name],
stdin=f,
capture_output=True,
text=True
)
以上!