【Python】SQLAlchemyの使い方【データベース操作】

アイキャッチ画像
  • SQLAlchemyの使い方とは?
  • PythonでO/Rマッパーを扱うには?

本記事ではこのような疑問を解決します。


Pythonでデータベース操作を行う際によく登場するのがSQLAlchemyです。

DjangoのようなフルスタックなWebフレームワークではなく、
FlaskやBottleといった軽量なWebフレームワークを扱う場合はO/RマッパーとしてSQLAlchemyを使用することが多いでしょう。


そこで今回はSQLAlchemyの使い方を解説します。

あわせて読みたい

エンジニアが副業を始めるには?エンジニアの副業にはどんな種類がある? 本記事ではこのような疑問を解決します。副業がブームになっている昨今、エンジニアほど副業をやりやすい職業はないでしょう。副業に関心があったり、副業をしてみたいと思っ[…]

アイキャッチ画像

SQLAlchemyとは?

SQLAlchemyはPythonのO/Rマッパーライブラリの1つです。

O/Rマッパーとはオブジェクト指向プログラミング言語のオブジェクトとデータベース※の間でデータ変換を行うツールのことです。
※ここではリレーショナルデータベースのこと

ちなみに、O/Rマッパーは「Object-Relational Mappingを行うもの」という意味になります。

本来、データベースの操作にはMySQLやPostgreSQLなどのデータベース管理システムでSQL文によるクエリを発行する必要があります。

クエリとは処理要求を意味し、簡単にいうと、
データベースに対して「〇〇の操作をしろ!」といった命令文のことです。


そして、Pythonなどのオブジェクト指向プログラミング言語においてもクエリを発行してデータベースを操作できます。

ただ、素のSQL文を扱う場合、SQLについての知識が必要だったり、
MySQLやPostgreSQLなどのリレーショナルデータベース管理システム(RDBMS)の種類によってSQLの文法が異なってきたりといった不便が生じます。


そこで登場するのがO/Rマッパーです。

O/RマッパーであればSQLへの深い知識は求められず、各RDBMSによる差異を吸収してくれます。


さらに、それぞれが書き慣れているオブジェクト指向プログラミング言語っぽくコードを書いてデータベースを操作することができます。


したがって、今回ご紹介するSQLAlchemyであれば、
Pythonのコードを書くだけでデータベース操作が可能になるのです。

Pythonライブラリをインストールする

最初にSQLAlchemyライブラリをインストールしましょう。

$ pip install SQLAlchemy

データベースエンジンを作成する

ここでは接続するデータベースなどを指定します。

なお、データベースドライバーの記述を省略すると、
各データベースごとに用意されているDBAPIが使用されるようになります。

import sqlalchemy

engine = sqlalchemy.create_engine("{dialect}+{driver}://{username}:{password}@{host}:{port}/{database}?{queryparam})

・dialect:データベースの種類
例)sqlite、mysql、postgresqlなど

・driver:データベースドライバー※省略OK
例)mysql、psycopg2など

・username:ユーザ名

・password:パスワード

・host:IPアドレス

・port:ポート番号※省略OK

・database:接続先データベース名

・queryparam:クエリパラメータ※省略OK
例)charset=utf-8など

ちなみに、1番手っ取り早くSQLAlchemyを試したい方は以下のように記述すると良いでしょう。

import sqlalchemy

engine = sqlalchemy.create_engin('sqlite://:memory:')

上記の記述はデータベースにSQLiteを指定し、保存場所をメモリにしています。

あわせて読みたい

フリーランスエンジニアが案件獲得方法とは?自ら営業せずに案件を獲得するには?実務経験1年未満でも大丈夫なの? 本記事ではこのような疑問を解決します。これからフリーランスエンジニアとして独立したい方は、兎にも角にも案件の獲得が急務です[…]

アイキャッチ画像

モデルクラスを作成する

ベースクラスを作成する

まずはモデルクラスで継承するベースクラスをインスタンス化します。

このベースクラスを拡張することでモデルクラスによるテーブル定義をすることができます。

import sqlalchemy.ext.declarative

Base = sqlalchemy.ext.declarative.declarative_base()

テーブルを定義する

ここではテーブルを定義し、カラムを設定していきます。

先ほど作成したBaseクラスを継承します。

class Player(Base):
    __tablename__ = 'players'
    player_id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True)
    name = sqlalchemy.Column(sqlalchemy.String(30))
    comment = sqlalchemy.Column(sqlalchemy.Text)

データベースに登録する

create_all()を使って定義したメタデータ(テーブル情報)をデータベースに登録します。

引数には最初に定義したデータベースエンジンを渡します。

Base.metadata.create_all(engine)

セッションを作成する

SQLAlchemyでデータベースにアクセスするためにはセッションの作成が必要です。

すなわち、作成したセッションを介してクエリを実行しデータベースを操作していきます。

そして、セッションの作成方法はいくつかありますが、
トランザクション管理の観点からSessionインスタンスを呼び出す際に、
毎回同じインスタンスが呼び出されるようにする必要があります。

と、ここは少し難しい話になってくるため、
まずは以下のような記述でセッションを作成すれば良いということだけ覚えておきましょう。

from sqlalchemy.orm import scoped_session, sessionmaker

session = scoped_session(
    essionmaker(
        autocommit = False,
        autoflush = False,
        bind = engine
        )
    )

CRUD処理をする

テーブルやセッションを作成できたところで、実際にCRUD処理をしていきましょう。


CRUD処理とはデータベース操作における、
Create(作成)、Read(読み込み)、Update(更新)、Delete(削除)
の4つの基本的な処理のことです。

なお、CRUD処理をSQL文に対応させると、
Create → INSERT
Read → SELECT
Update → UPDATE
Delete → DELETE

というようになります。

INSERT

レコードを作成する場合はモデルクラスのインスタンスを生成し、add()を使うことで行います。

player = Player(name='Mike', comment='Hello, world!')
session.add(player)
session.commit()

SELECT

レコードを取得する場合はquery()にモデルクラスを渡し、filter()やall()を使うことで行います。

players = session.query(Player).all() # すべてのレコードをリストで取得する
player = session.query(Player).get(name='Mike') # nameがMikeのレコードを1件取得する(複数あるとエラーになる)
players = session.query(Player).filter(Player.name == 'Mike') # nameがMikeのレコードを全件取得する

UPDATE

レコードを更新する場合は対象レコードを取得し、各カラムの値に更新したい値を代入することで行います。

player = session.query(Player).get(name='Mike') # nameがMikeのレコードを1件取得する
player.name = 'Mike_2' # nameをMike_2に更新する
session.commit()

DELETE

レコードを削除する場合は対象レコードを取得し、delete()に渡すことで行います。

player = session.query(Player).get(name='Mike_2') # nameがMike_2のレコードを1件取得する
session.delete(player) # 取得したレコードを削除する
session.commit()

flush()とcommit()について

SQLAlchemyのSessionクラスにはflush()とcommit()というメソッドがあります。

flush()とcommit()はレコードをデータベースへ保存する時に使うメソッドです。

つまり、ここまで説明してきたCRUD処理の結果をデータベースへ反映させるためのメソッドになります。


なぜこの2つを取り上げたかというと、
SQLAlchemyでデータの登録や更新、削除の処理を行う際には必ず押さえておくべき内容だからです。


それでは両者を比較しつつ理解していきましょう。

○flush()
・CRUD処理(クエリ)の結果を一時的にデータベースに反映する
・ロールバック(rollback())するとクエリが無効になる
・コミット(commit())せずにSessionインスタンスを終了(close())させるとクエリが無効になる


○commit()
・クエリの結果を永続的にデータベースに反映する
・ロールバックしてもクエリは無効にならない

両者の違いをまとめると、
データを一時的に保持したい時はflush()を使い、
データの保存を確定させたい時はcommit()を使う、ということになります。


なお、両者の一般的な使い方は以下の通りです。

try:
    session = scoped_session(
        essionmaker(
            autocommit = False,
            autoflush = False,
            bind = engine
            )
        )

    player = Player(name='Mike')

    session.add(player)

    # ==============================
    # 何かしらの処理を行う
    # 必要に応じてflush()をする
    # ==============================

    session.commit()

except Exception as e:
    session.rollback()

    raise e

finally:
    session.close()

まとめ

以上がSQLAlchemyの使い方になります。


今回はSQLAlchemyの基本的な内容を解説しました。

ただ、基本的な内容とは言っても本記事をしっかり押さえることでさまざまな場面に応用することができるでしょう。

また、SQLAlchemyはSQL文を記述しなくても良いことがメリットですが、
どんなSQL文が発行されているかを意識することで処理速度の向上や最適なデータの取得方法などを実現できます。

そのため、SQL文も気にしつつ実装するととても勉強になります。


ぜひあなたのWebアプリケーション開発に活かしてみてください!

案件獲得

フリーランスエンジニアが案件獲得方法とは?自ら営業せずに案件を獲得するには?実務経験1年未満でも大丈夫なの? 本記事ではこのような疑問を解決します。これからフリーランスエンジニアとして独立したい方は、兎にも角にも案件の獲得が急務です[…]

アイキャッチ画像
副業

エンジニアが副業を始めるには?エンジニアの副業にはどんな種類がある? 本記事ではこのような疑問を解決します。副業がブームになっている昨今、エンジニアほど副業をやりやすい職業はないでしょう。副業に関心があったり、副業をしてみたいと思っ[…]

アイキャッチ画像