LoginSignup
31
31

More than 5 years have passed since last update.

【dataset】pythonでDB処理を楽チンに!【ORM】【python】

Posted at

はじめに

pythonからデータベースをいじる時に、クエリをベタ書きするんじゃなくてORMを利用することでコードがすっきりするのでサーバーサイドやデータサイエンスに興味ある人にはマストだと思います。

ORMとは?

オブジェクト関係マッピング(Object-Relational Mapping)の略称。

言語からSQLを操作する時に、SQLドライバを入れてクエリ書いて実行する(Ex. mysql-connecter)という方法がある。

でも、これだと上に書いたように処理が多い時に綺麗にコードが書きづらい!

ってことでそれを解消するのにORMが役にたつ!

簡単に言うとSQLを関数的に使うことができる。

今回使うpython用ORMは【dataset】

環境

OS:MacOS OSX10.11.6
言語:python3.5.2
ORM:dataset0.8.0
DBMS:mysql

導入

これだけ。

sudo pip install dataset

だけど、MySQLdbがimportできない!っていうエラー出ることがあります。

その時は、以下のパッケージをインストールしてください。

pip install mysqlclient

これで、python3でMySQLdbをimportすることができてdatasetをインストールすることができると思います。

実践

SQL文と対応させながら基本的な使い方を説明します。

今回は練習用に研究室のデータベースサーバー【db01】を使います。

データベースは【TrainLine】で、小田急線の駅名が入っています。

__________2017-04-15_22.43.26.png

接続

まず、DBと接続します。

import dataset

# 対象のDBを指定
DBMS = 'mysql'
USER = 'root'
PASS = '~'
HOST = '対象DBのIPアドレス'
DB     = 'TrainLine' 
TABLE='Station_Name'
# 文字コードで悩む人へ
CHARSET = 'utf8'

db = dataset.connect('{0}://{1}:{2}@{3}/{4}?charset={5}'.format(DBMS, USER, PASS, HOST, DB, CHARSET))
table = db[TABLE]

DBMS:MySQL,PostgreSQL,sqliteとか対象のDBMSを指定

USER:ログインしたいユーザー名を指定

PASS:パスワードが必要なユーザーの時は指定

HOST:サーバーのアドレスを指定(IPアドレスでも可)

DB:使用するDB名を指定

TABLE:使用するテーブル名を指定



これで実行してエラーが出なければ接続完了。

次に実際にSQLを実行していきます。

SELECT文(複数)

複数レコードをselectする時はfind()を使います。

# SQL:SELECT * FROM Station_Name
results = table.find()
for record in results:
    # OrderDict型で1レコードずつ出力される
    print(record)
    # カラムを指定することで特定の情報を引き出せる
    print(record['Station_ID'])
    print(record['Name'])

selectされたデータはOrderDict型で返ってきます。

ちなみにOrderDict型は、順番を保持した辞書型のデータです。

複数のレコードをselectしているため、for文を使うことで1レコードずついじれます。

1レコードに対して、カラムを指定することで情報を抽出できます。

terminal
===SQL:SELECT * FROM Staion_Name===
OrderedDict([('Station_ID', 2500101), ('Name', '新宿')])
2500101
新宿
OrderedDict([('Station_ID', 2500102), ('Name', '南新宿')])
2500102
南新宿
OrderedDict([('Station_ID', 2500103), ('Name', '参宮橋')])
2500103
参宮橋
OrderedDict([('Station_ID', 2500104), ('Name', '代々木八幡')])
2500104
代々木八幡
OrderedDict([('Station_ID', 2500105), ('Name', '代々木上原')])
2500105
代々木上原
・・・

WHERE句での指定SELECT

SQLで特定の情報を持つレコードをselectするのにWHERE句を使います。

このORMではfind関数の引数にカラムと値を指定することで実現できます。

## where句での指定
# SQL:SELECT * FROM Staion_Name WHERE Station_ID = 2500101
results = table.find(Station_ID=2500101)
for record in results:
    print(record)
terminal
===SQL:SELECT * FROM Staion_Name WHERE Station_ID = 2500101===
OrderedDict([('Station_ID', 2500101), ('Name', '新宿')])

LIMITの指定も可能

複数レコードをselectする際にレコード数を制限することができる。

## _limit変数でselectの数を制限
# SQL:SELECT * FROM Station_Name limit 10 
results = table.find(_limit = 10)
for record in results:
    print(record)
terminal
===SQL:SELECT * FROM Staion_ID = 2500101===
OrderedDict([('Station_ID', 2500101), ('Name', '新宿')])

SELECT文(単一)

単一のレコードだけをselectする時はfind_one()を使うとfor文を使わないでデータをいじれる。

# SQL:SELECT * FROM Staion_ID = 2500101
print(table.find_one(Station_ID = 2500101))
terminal
===SQL:SELECT * FROM Staion_Name limit 10===
OrderedDict([('Station_ID', 2500101), ('Name', '新宿')])
OrderedDict([('Station_ID', 2500102), ('Name', '南新宿')])
OrderedDict([('Station_ID', 2500103), ('Name', '参宮橋')])
OrderedDict([('Station_ID', 2500104), ('Name', '代々木八幡')])
OrderedDict([('Station_ID', 2500105), ('Name', '代々木上原')])
OrderedDict([('Station_ID', 2500106), ('Name', '東北沢')])
OrderedDict([('Station_ID', 2500107), ('Name', '下北沢')])
OrderedDict([('Station_ID', 2500108), ('Name', '世田谷代田')])
OrderedDict([('Station_ID', 2500109), ('Name', '梅ヶ丘')])
OrderedDict([('Station_ID', 2500110), ('Name', '豪徳寺')])

INSERT文(単一)

SQLだと覚えにくいINSERT文もORMを使うと直感的に操作できます。

INSERTしたいレコードデータは、dict型で生成します。

# INSERT文:insert()
# SQL:INSERT INTO Staion_Name VALUES (2500200, '新大久保')
## insertしたいレコード
data = dict(Station_ID=2500200, Name='新大久保')
table.insert(data)
for record in table.find(Station_ID=2500200): print(record)


terminal
===SQL:INSERT INTO Staion_Name VALUES (2500200, '新大久保')===
OrderedDict([('Station_ID', 2500200), ('Name', '新大久保')])
OrderedDict([('Station_ID', 2500200), ('Name', '新大久保')])

INSERT文(複数)

複数のレコードをいっきにINSERTする方法が以下です。

## 複数のinsert
print("===複数insert===")
table.insert_many([dict(Station_ID=2500201, Name='西日暮里'), dict(Station_ID=2500202, Name='五反田')])
time.sleep(3)
for ID in [2500201, 2500202]:print(table.find_one(Station_ID=ID))


terminal
===複数insert===
OrderedDict([('Station_ID', 2500201), ('Name', '西日暮里')])
OrderedDict([('Station_ID', 2500202), ('Name', '五反田')])

UPDATE文

INSERT文同様にレコードデータを生成します。

ポイントは生成したレコードとデータベースにあるUPDATEしたいレコードの値が共通のカラム(下ので例では、Station_ID)をupdate関数の第2引数に指定することです。

# UPDATE文:update()
# SQL:UPDATE Staion_Name SET (Name = 渋谷) WHERE Station_ID = 2500201
## updateしたいレコード
data = dict(Station_ID=2500201, Name='渋谷')
## updateするためのカラムを指定(第2引数)
table.update(data, ['Station_ID'])
print(table.find_one(Station_ID=2500201))


terminal
===SQL:UPDATE Staion_Name SET Name = 渋谷 WHERE Station_ID = 2500201===
OrderedDict([('Station_ID', 2500201), ('Name', '渋谷')])

DELETE文

削除したいレコードがあるときは、delete()を実行する。

delete関数の第1引数にレコードのプライマリキーのカラムと値を指定して削除ができます。

# DELETE文:delete()
# SQL:DELETE FROM Station_Name WHERE Station_ID = 2500202
for ID in [2500200, 2500201, 2500202]: table.delete(Station_ID=ID)
for ID in [2500201, 2500202]:print(table.find_one(Station_ID=ID))


terminal
===SQL:DELETE FROM Station_Name WHERE Station_ID = 2500202===
None
None

COUNT文

カラムの値を指定することでその値を持つレコード数を数えることができます。

このORMではWHERE句の不等式での指定ができないため、レコードが存在するかどうかに使えそう。

# COUNT文:count()
# SQL:SELECT COUNT(*) FROM Station_Name WHERE Station_ID = 2500101
## WHERE句は等式でしか指定できないためレコードを確かめるのとかに使える
print(table.count(Station_ID = 2500101))
print(table.count(Station_ID = 2500301))


terminal
===SQL:SELECT COUNT(*) FROM Station_Name WHERE Station_ID = 2500101===
1
0

終わりに

これでpython用ORM【dataset】の説明終わります。

最低限の使い方はわかると思います。

他にも機能を使いたければ、直接gitをリファレンスするといいと思います。



ORMは知っておいて損はない知識・技術だと思うので、自分が使い慣れてる言語で1つは身につけておくと良いと思います。

読んでくれた方の参考になれば幸いです。

参考URL

31
31
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
31
31