0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Tortoise ORM:今、みんなが使っている次世代のPython ORM

Posted at

Group239.png

Leapcell: 最適なサーバレス Web ホスティング

Tortoise ORM: asyncio に基づく強力なオブジェクト関係マッパー

Tortoise ORM は、Django ORM にインスペクトされた、Python 向けの使いやすい asyncio ORM(オブジェクト関係マッパー)です。Django ORM のデザインコンセプトを借りています。従来のテーブルデータの処理をサポートするだけでなく、関係データを効率的に管理することもできます。パフォーマンス面では、他の Python ORM に劣りません。

サポートされるデータベース

Tortoise ORM は現在、複数の主流のデータベースをサポートしています:

  • SQLiteaiosqlite で駆動され、軽量なアプリケーションのシナリオに適しています。
  • PostgreSQL:バージョンは >= 9.4 で、asyncpg(非同期モード)または psycopg(同期モード)ドライバをサポートしています。
  • MySQL/MariaDBasyncmy ドライバの助けを借りて、効率的な接続を実現します。
  • Microsoft SQL Serverasyncodbc ドライバを通じてデータのやり取りを完了します。

環境設定とインストール

  1. Tortoise ORM のインストール
pip install tortoise-orm
  1. 対応するデータベースドライバのインストール
    • PostgreSQL(非同期):
    pip install tortoise-orm[asyncpg]
    
    • MySQL/MariaDB:
    pip install tortoise-orm[asyncmy]
    
    • SQLite: デフォルトでサポートされており、追加のドライバのインストールは不要です

データベース接続設定

SQLite

接続文字列の形式は sqlite://DB_FILE です。例えば、データベースファイルが /data/DB.sqlite3 の場合、完全な接続文字列は sqlite:///data/db.sqlite3(スラッシュが 3 つ注意)です。

MySQL

接続文字列の形式: mysql://user:password@host:3306/somedb、パラメータの説明:

  • user: データベースのユーザ名
  • password: ユーザパスワード
  • host: データベースのホストアドレス
  • port: データベースのポート(デフォルトは 3306)
  • database: 接続するデータベースの名前

PostgreSQL

  • 非同期モード: asyncpg://postgres:pass@db.host:5432/somedb
  • 同期モード: psycopg://postgres:pass@db.host:5432/somedb

Microsoft SQL Server

接続文字列の形式: mssql://user:pass@host:1433/db?driver=theodbcdriver、パラメータの説明:

  • user: ユーザ名
  • password: パスワード
  • host: ホストアドレス
  • port: ポート(デフォルトは 1433)
  • database: データベース名
  • driver: ODBC ドライバ名で、odbcinst.ini ファイルで設定する必要があります

データベースの作成と初期化

from tortoise import Tortoise, run_async

async def init():
    # SQLite データベースを使用し、ファイル名は db.sqlite3
    # モデルを含むアプリケーション名を "models" と指定する
    await Tortoise.init(
        db_url='sqlite://db.sqlite3',
        modules={'models': ['models']}
    )
    # データベーステーブル構造を生成する
    await Tortoise.generate_schemas()  # safe パラメータ: True に設定すると、テーブルが存在しない場合のみ作成されます

run_async(init())  # 自動的にコンテキストを処理し、操作終了後にデータベース接続を閉じます

MySQL データベースを使用する場合、まず tortoise-orm[aiomysql] 依存関係をインストールする必要があります。

モデル定義

from tortoise.models import Model
from tortoise import fields
from tortoise.manager import Manager

class Team(Model):
    id = fields.IntField(pk=True)
    name = fields.TextField()

    class Meta:
        abstract = False  # 抽象クラスかどうか、True の場合、データテーブルは生成されません
        table = "team"  # テーブル名、設定しない場合、クラス名がデフォルトで使用されます
        table_description = ""  # テーブルのコメント
        unique_together = ()  # 複合ユニークインデックス
        indexes = ()  # 複合非ユニークインデックス
        ordering = []  # デフォルトのソート
        manager = Manager  # カスタムマネージャ

フィールドの種類

データフィールド

from tortoise import fields

fields.Field(
    source_field=None,  # カスタムデータベースカラム名
    generated=False,  # データベースで自動生成されるかどうか
    pk=False,  # 主キーかどうか
    null=False,  # フィールドが空にできるかどうか
    default=None,  # デフォルト値
    unique=False,  # 値が一意かどうか
    index=False,  # インデックスを作成するかどうか
    description=None,  # フィールドの説明
    validators=None  # バリデータのリスト
)

関係フィールド

  1. 外部キーフィールド
fields.ForeignKeyField(
    model_name,  # 関連するモデル名、{app}.{models} の形式
    related_name=None,  # 逆解決属性名
    on_delete='CASCADE',  # 削除戦略、選択肢: CASCADE, RESTRICT, SET_NULL, SET_DEFAULT
    db_constraint=True,  # データベースで外部キー制約を作成するかどうか
)
  1. 1 対 1 フィールド
fields.OneToOneField(
    model_name,
    related_name=None,
    on_delete='CASCADE',
    db_constraint=True
)
  1. 多対多フィールド
fields.ManyToManyField(
    model_name,
    through=None,  # 中間テーブル
    forward_key=None,  # 前方検索キー
    backward_key='',  # 逆検索キー
    related_name='',
    on_delete='CASCADE',
    db_constraint=True
)

照会操作

モデルは複数の照会メソッドを提供しています:

  • filter(*args, **kwargs): 条件に応じてデータをフィルタリングします
  • exclude(*args, **kwargs): 条件を満たすデータを除外します
  • all(): すべてのデータを取得します
  • first(): 最初のデータを取得します
  • annotate(): 集計照会を行います

filter メソッドがサポートする照会条件:

  • 範囲照会: in, not_in, gte, gt, lte, lt, range
  • null 値照会: isnull, not_isnull
  • 文字列照会: contains, icontains, startswith, istartswith, endswith, iendswith, iexact
  • 全文検索: search

以下はいくつかの具体的な照会の例です:

単純な照会の例

Team モデルが定義されているとします:

from tortoise import run_async
from models import Team  # モデルは models.py ファイルに定義されていると仮定

async def simple_query():
    # すべての Team レコードを取得する
    all_teams = await Team.all()
    print("All teams:", all_teams)

    # 最初の Team レコードを取得する
    first_team = await Team.first()
    print("The first team:", first_team)

    # 条件に基づいてフィルタリングし、名前が "Team A" のチームを取得する
    filtered_teams = await Team.filter(name="Team A")
    print("Teams named Team A:", filtered_teams)

run_async(simple_query())

範囲照会の例

from tortoise import run_async
from models import Team

async def range_query():
    # id が 5 より大きいチームを照会する
    greater_than_5 = await Team.filter(id__gt=5)
    print("Teams with id greater than 5:", greater_than_5)

    # id が 2 から 8 の範囲(2 と 8 を含む)のチームを照会する
    in_range = await Team.filter(id__range=(2, 8))
    print("Teams with id between 2 and 8:", in_range)

    # id が [1, 3, 5] に含まれないチームを照会する
    not_in_list = await Team.filter(id__not_in=[1, 3, 5])
    print("Teams whose id is not in [1, 3, 5]:", not_in_list)

run_async(range_query())

文字列照会の例

from tortoise import run_async
from models import Team

async def string_query():
    # 名前に "team" という文字列を含むチームを照会する(大文字小文字を区別しない)
    contains_team = await Team.filter(name__icontains="team")
    print("Teams whose name contains team (case-insensitive):", contains_team)

    # 名前が "A" で始まるチームを照会する(大文字小文字を区別する)
    startswith_A = await Team.filter(name__startswith="A")
    print("Teams whose name starts with A:", startswith_A)

    # 名前が "B" で終わるチームを照会する(大文字小文字を区別しない)
    endswith_B = await Team.filter(name__iendswith="B")
    print("Teams whose name ends with B (case-insensitive):", endswith_B)

run_async(string_query())

より詳細な使い方については、Tortoise ORM 公式ドキュメントを参照してください。

Leapcell: 最適なサーバレス Web ホスティング

最後に、Python サービスをデプロイするのに最適なプラットフォームをお勧めします:Leapcell

brandpic7.png

🚀 好きな言語で構築

JavaScript、Python、Go、または Rust で簡単に開発できます。

🌍 無料で無制限のプロジェクトをデプロイ

使用した分だけ支払います — リクエストがなければ、請求はありません。

⚡ 使った分だけ支払い、隠された費用はありません

アイドル料金はなく、シームレスなスケーラビリティを実現します。

Frame3-withpadding2x.png

📖 ドキュメントを参照

🔹 Twitter でフォローしてください: @LeapcellHQ

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?