pythonのmysqldbの使い方メモ

pythonからMySQL叩くのに、まだO/Rマッパを習得してないのでもっぱらMySQLdb/pymysqlを使っているのですが、中々すらすら書けるようにならないのでエントリを書いて無理矢理覚えるメソッドです。

先ずAPIリファレンスに中々たどり着かなかったのでリンクを張っておきます。

それで取りあえずは、以下のコードをすらすら書ければ、最低限は事足りる気がします。注意が必要なのはUPDATEの際はcommitが必要なのと、プレースホルダを使う際はクォーテーションが不要な事でしょうか。後DictCursorを使うとSELECTで取得した各行が辞書オブジェクトになって便利だと思います。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import MySQLdb
from MySQLdb.cursors import DictCursor 

def process_row(row):
  print row

con = MySQLdb.connect(host='localhost', db='testdb', user='testuser', passwd='testpass')
# SELECT
cur = con.cursor()                        # connectionから取得したcursorからsqlを発行する
print cur.execute('SELECT * FROM books')  # executeは行数を返却
res = cur.fetchall()                      # fetchone, fetchmany, fetchallで結果取得
for row in res:
  process_row(row)                        # 各行はtuple (10L, 'Book A', 1000L, None)

# INSERT
# executemanyでパラメータが違うだけの複数のSQLを一気に実行できる
print cur.executemany('INSERT INTO books(title, price) VALUES(%s, %s)',
                [('Book A', 1000),       # プレースホルダーは%s固定でかつクォーテーション不要('%s'とはしない)
                ('Book B', 2000),        # INSERTは即時反映 (commit不要)
                ('Book C', 3000)])
# UPDATE
print cur.execute('UPDATE books SET is_finish = true WHERE title = %s', ('Book A',))
con.commit()   # UPDATEのみcommitしないと反映されない

# DELETE
print cur.execute('DELETE FROM books WHERE id = %s', (1,))  # DELETEも即時反映
cur.close()

# カーソルはDictCursorも選べる
cur = con.cursor(DictCursor)
print cur.execute('SELECT * FROM books')
res = cur.fetchall()                    
for row in res:
  process_row(row)   # 各行は辞書 {'price': 1000L, 'is_finish': 1, 'id': 19L, 'title': 'Book A'}

# 後片付け
cur.close()
con.close()

コメントだらけで汚いコード失礼しましたです。それにしてもcursor一々取得必要でexecuteとfetchも別なんて、どんだけ面倒やねんと思いますね。早いところO/Rマッパを習得した方が良いかもですね。

一応上記コードで使っているbooksテーブルのcreate文も書いておきます。

 CREATE TABLE `books` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` text,
  `price` int(11) DEFAULT NULL,
  `is_finish` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

4 thoughts on “pythonのmysqldbの使い方メモ”

  1. データの挿入(insert) でも commit() が必要でした。
    参照するだけなら、反映する必要がない。
    なにかデータに変更を加えたなら、 commit() する。
    でしょうか?

    参考になりました。ありがとうございました。

    MySQLdb ver 1.2.3
    python 2.7
    MySQL 5.5.16

Leave a Reply

Your email address will not be published. Required fields are marked *