Python で MySQL の操作が可能な ORM peewee
はじめに
Python で MySQL の操作が可能な ORM(OR Mapper) の peewee についての調査メモ。
公式ドキュメントはここ。
目次
環境・条件
1 | $ sw_vers |
詳細
peewee について
「MySQL の操作が〜」と書いたが、peewee 自身は MySQL だけでなく sqlite, postgresql にも対応した ORM である。
DB 接続
peewee.MySQLDatabase で DB に接続する。
1 | import peewee |
正常に接続できている場合は connect で True が返ってくる。
1 | db.connect() |
connect_params で、接続時のパラメータが確認できる。
なお、接続時に 'charset' を省略した場合は utf8 になるため、システムによっては問題となる可能性があると思われる。詳しくはこちらを参照。
1 | db.connect_params |
接続中の DB は database で確認できる。
1 | db.database |
テーブル一覧 取得
get_tables でテーブル一覧が取得可能。アルファベット昇順の List で返却される。
1 | db.get_tables() |
テーブル 作成
create_tables 、あるいは create_table でテーブル作成。事前にテーブル(モデル)を class で定義しておく必要がある。
1 | class User(peewee.Model): |
MySQL 側で見ると以下のような状態となっている。
idフィールドはデフォルトで作られる- Big Integer ではないので注意(バージョンで 違う/変わる かも)
created_at,updated_atなどは無い- 欲しい場合は
peewee.DateTimeFieldで定義する必要がある
- 欲しい場合は
1 | mysql> DESC user; |
テーブル名を複数形にする
単純にクラス名を Users のようにすれば users としてテーブルが作成される。
1 | class Users(peewee.Model): |
1 | mysql> show tables; |
キャメルケース(パスカルケース)のテーブル名を _(アンダースコア) 区切りにする
UserProfile というクラス名でテーブルを作ると、userprofile というテーブル名になる。
user_profile というテーブル名にしたい場合には、Meta クラスの中で legacy_table_names = False にすると良い。
1 | class UserProfile(peewee.Model): |
テーブル名を自分で設定する
「モデルは単数形のままで、テーブル名は複数形にしたい」とか「キャメルケース(パスカルケース)で、_(アンダースコア)区切りにしたい」とか、細かいこだわりがある場合には、Meta クラスの中で table_name を直接設定すれば OK。
1 | class User(peewee.Model): |
Big Integer で id フィールドを定義
BigAutoField と primary_key=True の組合せで定義すれば良い。
1 | class User(peewee.Model): |
1 | mysql> desc user; |
ForeignKeyField との連携
Field types table には ForeignKeyField は Integer と書かれているが、参照先が BigInt なら ForeignKey も BigInt になる。
ForeignField not compatible with BigAutoField · Issue #1630 · coleifer/peewee で対応されている。
利用可能フィールド
Field types table を参照。
ForeignKeyField: 外部キー制約
外部キー制約は ForeignKeyField で定義する。
1 | from peewee import * |
親データ削除とともに、子データも消したい場合には on_delete="CASCADE" を設定。デフォルトは RESTRICT なので、子データを消してからじゃないと親データを消せない。
「CASCADE? RESTRICT??」って人は MySQLの外部キー制約RESTRICT,CASCADE,SET NULL,NO ACTIONの違いは? - Qiita を参照。
1 | from peewee import * |
フィールドオプション
デフォルト値の設定や、NOT NULL 制約なども指定可能。
詳細は Field initialization arguments を参照。
デフォルト値
default オプションで指定。
1 | class User(peewee.Model): |
NOT NULL 制約
null オプションで指定。
True: NULL OK(許容)False: NULL NG(非許容)
1 | class User(peewee.Model): |
UNIQUE 制約
unique オプションで指定。
True: UNIQUE 制約ありFalse: UNIQUE 制約なし
1 | class User(peewee.Model): |
複合 UNIQUE 制約
class Meta: の中で定義、複合インデックスにしたいカラムをタプルで渡して、ユニーク制約をかける場合には True を指定する。
1 | class User(peewee.Model): |
テーブル 削除
drop_tables、あるいは drop_table でテーブル削除。
1 | db.drop_tables([User]) # or User.drop_table() |
データ 追加
create、あるいは定義したモデルのインスタンス作成 + save でデータ作成。
1 | class User(peewee.Model): |
データ 更新
get_by_idなどでデータ取得して、whereと組み合わせる方法もあるUser.update({User.name: "hoge"}).where(User.id == 1).execute()
1 | user = User.get_by_id(1) |
その他・メモ
MySQL driver not installed! と出る場合
PyMySql などの MySQL Driver が入ってないと peewee.ImproperlyConfigured: MySQL driver not installed! のエラーで DB 接続できないので注意。
1 | db.table_exists("users") |
PyMySql をインストールすることで解決。
1 | $ pip install pymysql |
参考文献
- coleifer/peewee: a small, expressive orm -- supports postgresql, mysql and sqlite
- peewee — peewee 3.9.6 documentation
- PythonのORMのPeeweeを使ってデータベースを操作してみる - Qiita
- MySQL で utf8 と utf8mb4 の混在で起きること - @tmtms のメモ
関連記事
- Python boto3 で AWS S3 を操作する
- MySQL でユニーク制約と論理削除を同時に実現する方法
- docker-lambda を使って AWS Lambda Function を開発する方法
- Python requests + boto3 で AWS S3 に画像を直接アップロード
- Rails で既存の DB を利用するアプリケーションの作成方法(DB 参照のみ)
- Python requests で画像をダウンロードして保存する方法
- JavaScript で URL のクエリパラメータを操作する方法
- jQuery Select2 で、初期値の設定と選択状態のクリア