Tortoise ORM:次世代Python ORM、みんなが話す
Ethan Miller
Product Engineer · Leapcell

Tortoise ORM: asyncioに基づく強力なオブジェクト関係マッパー
Tortoise ORMは、Django ORMに触発された、Python用の使いやすいasyncio ORM(オブジェクト関係マッパー)です。Django ORMの設計コンセプトを参考にしています。従来の表形式データの処理をサポートするだけでなく、リレーショナルデータを効率的に管理できます。パフォーマンスに関しては、他のPython ORMに劣ることはありません。
サポートされるデータベース
Tortoise ORMは現在、複数の主流データベースをサポートしています。
- SQLite:
aiosqlite
によって駆動され、軽量なアプリケーションシナリオに適しています。 - PostgreSQL: バージョンは>= 9.4である必要があり、
asyncpg
(非同期モード)またはpsycopg
(同期モード)ドライバをサポートします。 - MySQL/MariaDB:
asyncmy
ドライバの助けを借りて、効率的な接続を実現します。 - Microsoft SQL Server:
asyncodbc
ドライバを介してデータインタラクションを完了します。
環境構成とインストール
- Tortoise ORMのインストール
pip install tortoise-orm
- 対応するデータベースドライバのインストール
- 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 # バリデーターのリスト )
リレーションシップフィールド
- 外部キーフィールド
fields.ForeignKeyField( model_name, # 関連するモデル名、{app}.{models}の形式 related_name=None, # 逆解決属性名 on_delete='CASCADE', # 削除戦略、オプションの値:CASCADE、RESTRICT、SET_NULL、SET_DEFAULT db_constraint=True, # データベースに外部キー制約を作成するかどうか )
- 1対1フィールド
fields.OneToOneField( model_name, related_name=None, on_delete='CASCADE', db_constraint=True )
- 多対多フィールド
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: 最高のサーバーレスウェブホスティング
最後に、Pythonサービスのデプロイに最適なプラットフォームをお勧めします:Leapcell
🚀 お気に入りの言語で構築
JavaScript、Python、Go、またはRustで簡単に開発できます。
🌍 無制限のプロジェクトを無料でデプロイ
使用した分だけ支払います—リクエストも料金もありません。
⚡ 従量課金制、隠れたコストなし
アイドル料金はなく、シームレスなスケーラビリティだけです。
🔹 Twitterでフォローしてください:@LeapcellHQ