ヒトリ歩き

愚痴とかいろいろ書きます

データベース連携に便利なPython ORMツール - SQLAlchemy

SQLAlchemyを使うことが増えてきたので・・・。

SQLAlchemy とは?

SQLAlchemyは、Python向けのORM(オブジェクト リレーショナル マッパー)。 効率的かつ高パフォーマンスデータベースアクセスを目的に設計されているとのこと。

www.sqlalchemy.org

データベースと連携する

@arkuchyさんの記事を参考にさせていただいています。 詳しい解説なので、こちらをみてもらえると分かりやすいです。

qiita.com

sqlalchemyのクイックスタートをベースにお試し。

docs.sqlalchemy.org

テーブル定義が簡単に書ける

SQL文を頑張って書かなくてもテーブルが作成できる。
モデルベースクラスを作成するために、Base = declarative_base()を宣言していたが、2.0からは不要。 その代わりに、DeclarativeBaseクラスを継承したBaseクラスを宣言する。 また、カラムの定義はmapped_columnを使用するようになっている。 Columnも使用可能。

# モデルベースクラスを作成
#Base = declarative_base() と同等(2.0から)
class Base(DeclarativeBase):
    pass

# モデルベースを拡張して、ORMのデータクラスを作成
# mapped_columnは2.0からの新機能
class Product(Base):
    __tablename__ = "product"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    cost: Mapped[int] = mapped_column(Integer, nullable=False)
   
   

上記のモデルクラスは以下のテーブルと同じ。

CREATE TABLE product (
        id SERIAL NOT NULL, 
        name VARCHAR(255) NOT NULL, 
        cost INTEGER NOT NULL, 
        PRIMARY KEY (id)
)

検索、登録、更新、削除はORMを使うと楽だね

エンジン作成時にecho=Trueを設定すると、発行したSQL文を標準出力する。

# DBエンジンを作成
url = "postgresql://postgres:example@localhost:5432/postgres"
engine = create_engine(url, echo=True)

# テーブルをDBに作成
Base.metadata.create_all(engine)

# セッションを作成
# セッションを介してクエリを実行する
SessionClass = sessionmaker(engine)
session = SessionClass()

データの登録/更新/削除もORMを使うと簡単に出来る。

データを登録する場合、データクラスに値を設定して、登録用の関数を実行する。 データを更新する場合、対象のレコードのデータを取得して、データクラスを書き換える。 データを削除する場合、更新時と同様にデータを取得して、データクラスを削除用関数にパラメータとして渡す。

# Insert
product1 = Product(name="チョコ", cost=100)
product2 = Product(name="ガム", cost=10)
session.add_all([product1, product2])
session.commit()

# 検索
stmt = select(Product).where(Product.name.in_(["チョコ"]))
products = session.scalars(stmt)
for product in products:
    print("Name = " + str(product.name))

# 変更
stmt = select(Product).where(Product.id == 1)
product = session.scalars(stmt).one()
product.name = "パン"
session.commit()

# 削除
stmt = select(Product)
products = session.scalars(stmt)
session.delete(product)

さいごに

ORMを使うとSQLは意識しなくていいので、楽。
joinとかfunctionとかはどうしたらいいのかわからないので、もう少し調べてみる。