0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python x MySQL】PyMySQLドライバの仕様では、複数SQL文実行時にエラーが起きる?!

0
Posted at

概要

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
  )

以上!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?