Python3でMySQLを使う – 基本操作からエラー処理までサンプルコード付

WEBのシステム開発はPHPを使用していますが、データ解析等のため Python3 の研究を始めました。Python3 は日本語の情報がとても少ないので、エンジニアや学生の皆さんに役立ちそうなことをブログ記事として共有できればと思います。

この記事では Python3 で MySQL に接続する方法、エラー処理(例外処理)、サンプルによるCRUD(※)、PHPer向け注意点についてまとめました。なおサンプルは Django 等、特定フレームワークの ORM ではなく、SQLの直接実行例です。

SQLite3 は Python3でSQLite3を使う – 基本操作からエラー処理までサンプルコード付を参照ください。

※ CRUD とは Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)の略です。MySQL の場合Read に相当するのは主に Select 文になります。

Python3 で MySQL を使うための準備

Python3 には MySQL を操作する標準モジュールはありません。MySQL を操作するために、まず mysqlclient をインストールしましょう。

関連する公式ページ
https://pypi.python.org/pypi/mysqlclient/
https://mysqlclient.readthedocs.io/

スクリプトからも操作できますが、あらかじめ MySQL でデータベース sample_db を作っておきましょう。

では CRUD の操作をみていきます。

接続 / CREATE / INSERT

接続からテーブル作成・データ挿入まで、よくある操作をサンプルコードにまとめてみました。

ポイント解説

エラー処理

MySQL の操作上のエラーは MySQLdb.Error により処理できます。データベースの操作に予期せぬエラーはつきものなので、必ず例外処理をしておきましょう。上のサンプルソースでもわざと不正なSQLを実行して例外を発生させています。

上記サンプルではデータベース接続にあたって例外処理をしていませんが、外部ホストへの接続のような不安定なケースでは MySQLdb.Error で例外処理をしておきましょう。

プレースホルダ

プレースホルダには ? (疑問符)が使われることが多いですが MySQLdb では %s を用います。名前つきプレースホルダも %(hoge)s といったように利用できるようです(上のサンプルコードを参照)。

PHPer 向け注意事項

PHP の PDO は INSERT / UPDATE / DELETE 文の実行と同時にデータの更新が行われますが、Python3 + MySQLdb では(上のサンプルコードの最終行のように)必ずコミットをする必要があります。connection.commit() を忘れるとデータが保存されないことに注意しましょう。なお MySQLdb に限ったことではなく、Python3標準モジュールのSQLite3でも同様です。

connection.autocommit(True) をあらかじめ実行することで PHP と同様の動作にすることもできますが、郷に入れば郷に従えです。

SELECT

SELECT文を使ってよくやることをまとめてみました。件数取得、全件データ取得、1件データ取得、WHERE句など大抵のことは下記サンプルでわかるかと思います。

ポイント解説

全件ループ表示は上のように2パターンありますので、どちらも覚えておくのがよいです。パフォーマンスはどちらも違いはないでしょう(?)。cursor.fetchall() の方は全件取得してループするのだとわかりますが、for row in cursor: でなぜループ表示できるのか?不思議に思うかもしれません。(内部的なことは知らなくてもよいのですが)イテレータという仕組みがあるからこのようにシンプルに書けるのです。

PHPer 向け – 辞書型(連想配列)で取得するには?

PHP の PDO の場合、結果セットは $row[‘name’] のように連想配列で受け取れますが、cursor.fetchone() , cursor.fetchall() ともに結果セットは 0 で始まる単純な配列(正確にはタプルというデータ型)になっています。PDO::FETCH_NUM と同じ挙動です。

row[0], row[1] ではなく、row[‘id’], row[‘name’] のように結果セットを連想配列(Python では辞書型と呼びます)で受け取りたいケースも多いかと思います。カーソルオブジェクト生成の時に MySQLdb.cursors.DictCursor を引数に指定してみましょう。

MySQLdb.cursors.DictCursor を指定したカーソルは結果セットを辞書型で返すため、row[‘name’] のように扱え、PHP PDO の PDO::FETCH_ASSOC と同様になります。

参考: http://php.net/manual/ja/pdostatement.fetch.php

UPDATE / DELETE

UPDATE と DELETE には特別なことはありません。上の INSERT と同様にコミットしないと変更が保存されないこと、適宜 MySQLdb.Error で例外処理をすることを忘れないようにしましょう。

以上、Python3 で MySQL を使う方法をまとめてみました。弊社の専門はPHP言語なので、おかしなところがあればご指摘ください。
※この記事の内容は適宜更新することがあります。