見出し画像

PostgreSQLをPythonで操作する🔰

前回の記事でPostgreSQLのサーバー立ち上げとテーブル作成までできたので、今回はPythonのプログラムからDB操作をします。


1.Pythonライブラリの準備

PythonからPostgreSQLの操作をするための準備をしていきます。
主にこちらの記事を参考にさせていただきました。

私は現在 Pipenv で開発をしているので、開発ディレクトリに移動し、必要なライブラリを pipenv コマンドでインストールしていきます。

ドライバー : psycopg2

データベースと Python をつなぐには「ドライバー」が必要です。
PostgreSQL の場合は psycopg2 というライブラリを使います。
読み方が気になり海外の動画を見たところ「サイコピージーツー」でした。
調べている途中に、見てるとちょっと不安な気持ちになる psycopg2 のロゴも発見しました。

psycopg2 も仮想環境にインストールします。
psycopg2 のインストール時にエラーが出たら、コンパイル済みのバイナリパッケージ「psycopg2-binary」を使う方法もあります。(バイナリパッケージはあくまで開発用)
今回は特にエラーにはならなかったため、そのまま psycopg2 を使います。

pipenv install psycopg2

# バイナリパッケージ
pipenv install psycopg2-binary

⚠️ psycopg2は同期ドライバーなので、非同期のSQLAlchemyには対応していません。非同期に対応する場合はasyncpgを使用してください。

ORM : SQLAlchemy

次に、SQLを簡略化したり、Pythonのコードでデータベースを操作できるORMというものを使えるようにします。
Pythonで一番使われているORMライブラリはSQLAlchemyとのことで、こちらもインストールします。

pipenv install sqlalchemy

SQLAlchemyは「psycopg2」をデフォルトのドライバーとしているので、下記のように接続文字列に「postgresql」を指定すると、自動的にpsycopg2を使用するみたいです。なのでSQLAlchemyを使う場合、psycopg2がないとエラーになります。

2. Pythonからレコード追加

SQLAlchemyでのデータベース操作の仕方、コードは下記を参考にさせていただきました。

下記の構成でファイルを作っていきます。

/project_root
│── .env # 環境変数を管理(DATABASE_URLをここに記載)
│── main.py # 実行ファイル(ユーザー追加処理を記述)
│── db.py # データベース接続・セッションの設定
│── models.py # SQLAlchemyのモデル定義

環境変数の準備

まず .env ファイルに、下記のデータベース接続情報を追加します。URLの{}の部分は、下記の通り設定してください。

user : DBにアクセスできるユーザー名
password : DBにアクセスできるユーザーのパスワード
database : データベース名

▼ .env

DATABASE_URL="postgresql://{user}:{password}@localhost:5432/{database}"

データベース接続

次に、データベース接続とセッション管理を行うプログラムを作成します。
▼ db.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import os
from dotenv import load_dotenv

load_dotenv()  # .envファイルの読み込み

# データベース接続
DATABASE_URL = os.getenv("DATABASE_URL")
engine = create_engine(DATABASE_URL)

# セッションの作成
SessionLocal = sessionmaker(bind=engine)

# セッションを取得するための関数
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

モデルの定義

次にデータベースのモデル定義を行います。
▼ models.py

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class TestUser(Base):
    __tablename__ = 'test_user'

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String)
    age = Column(Integer)

declarative_base() は、SQLAlchemyでデータベースのモデル(テーブル構造)を定義するときに使う「基盤となるクラス」を作成するための関数です。
この Base を継承することで、テーブルの構造を簡単に定義できます。

テーブルを作成・行を追加する

ここに、実行したい更新処理を書いていきます。
▼ main.py

from sqlalchemy.orm import Session
from db import engine, get_db
from models import Base, TestUser

# テーブル作成
Base.metadata.create_all(bind=engine)

# ユーザー追加処理
def add_user(db: Session, name: str, age: int):
    new_user = TestUser(name=name, age=age)
    db.add(new_user)
    db.commit()
    print("ユーザーを追加しました。")

# 実行処理
if __name__ == "__main__":
    db = next(get_db())
    add_user(db, "Alice", 25)

Base.metadata.create_all() : Base を継承しているすべてのクラス(テーブル) がデータベースに作成されます。
前回の記事でテーブルは作成済みですが、テーブルがない場合のみ作成してくれます。

add_user() : test_user にユーザーを追加する関数です。

db = next(get_db()) : データベースセッションを取得し、add_user を実行したあと、get_db()のfinalyの処理でセッションを close します。

実行結果の確認

「main.py」を実行したあと、pgAdmin 4 でテーブルをセレクトして中身を確認すると、1行追加されているのが確認できました。

3.Pythonからレコード検索

先程のプログラムを元に、名前を検索してレコードの中身を参照する処理を追加します。
▼main.py

from sqlalchemy.orm import Session
from db import engine, get_db
from models import Base, TestUser

# テーブル作成
Base.metadata.create_all(bind=engine)

# ユーザー追加関数
def add_user(db: Session, name: str, age: int):
    new_user = TestUser(name=name, age=age)
    db.add(new_user)
    db.commit()
    print("ユーザーを追加しました。")

# ユーザーを名前で取得する関数
def get_user_by_name(db, name: str):
    return db.query(TestUser).filter(TestUser.name == name).first()


# 実行処理
if __name__ == "__main__":

    db = next(get_db())

    #  ユーザー追加
    add_user(db, "Alice", 25)
    add_user(db, "Bob", 30)

    #  名前で検索  
    user = get_user_by_name(db, "Bob")
    if user:
        print(f"検索結果: ID={user.id}, 名前={user.name}, 年齢={user.age}")
    else:
        print("ユーザーが見つかりません")

ユーザー検索用の関数 def get_user_by_name() を追加して、実行処理にこの関数の呼び出しも加えました。

▼ 実行結果 以下のようにレコードが取得できました。

ユーザーを追加しました。
ユーザーを追加しました。
検索結果: ID=7, 名前=Bob, 年齢=30

これでPythonを使った基本的なデータベース操作は可能になりました。
ここからはモデル定義を増やしていったり、自分に必要なデータ管理ができるようにカスタマイズしていきたいです。

いいなと思ったら応援しよう!