Tortoise ORM: Der Next-Gen Python ORM, von dem alle sprechen
Ethan Miller
Product Engineer · Leapcell

Tortoise ORM: Ein leistungsstarker Object Relational Mapper basierend auf asyncio
Tortoise ORM ist ein einfach zu bedienender asyncio ORM (Object Relational Mapper) für Python, inspiriert von Django ORM. Es entlehnt das Designkonzept von Django ORM. Es unterstützt nicht nur die Verarbeitung traditioneller tabellarischer Daten, sondern kann auch relationale Daten effizient verwalten. In Bezug auf die Leistung steht es anderen Python ORMs in nichts nach.
Unterstützte Datenbanken
Tortoise ORM unterstützt derzeit mehrere gängige Datenbanken:
- SQLite: Angetrieben von
aiosqlite
, geeignet für leichtgewichtige Anwendungsszenarien. - PostgreSQL: Die Version sollte >= 9.4 sein und
asyncpg
(asynchroner Modus) oderpsycopg
(synchroner Modus) Treiber unterstützen. - MySQL/MariaDB: Erreicht eine effiziente Verbindung mit Hilfe des
asyncmy
Treibers. - Microsoft SQL Server: Schließt die Dateninteraktion über den
asyncodbc
Treiber ab.
Umgebungskonfiguration und Installation
- Tortoise ORM installieren
pip install tortoise-orm
- Den entsprechenden Datenbanktreiber installieren
- PostgreSQL (Asynchron):
pip install tortoise-orm[asyncpg]
- MySQL/MariaDB:
pip install tortoise-orm[asyncmy]
- SQLite: Standardmäßig unterstützt, keine zusätzliche Treiberinstallation erforderlich
Datenbankverbindungskonfiguration
SQLite
Das Verbindungszeichenkettenformat ist sqlite://DB_FILE
. Wenn die Datenbankdatei beispielsweise /data/DB.sqlite3
ist, lautet die vollständige Verbindungszeichenkette sqlite:///data/db.sqlite3
(beachten Sie die drei Schrägstriche).
MySQL
Das Verbindungszeichenkettenformat: mysql://user:password@host:3306/somedb
, Parameterbeschreibung:
user
: Datenbankbenutzernamepassword
: Benutzerpassworthost
: Datenbankhostadresseport
: Datenbankport (Standard ist 3306)database
: Der Name der Datenbank, zu der eine Verbindung hergestellt werden soll
PostgreSQL
- Asynchroner Modus:
asyncpg://postgres:pass@db.host:5432/somedb
- Synchroner Modus:
psycopg://postgres:pass@db.host:5432/somedb
Microsoft SQL Server
Das Verbindungszeichenkettenformat: mssql://user:pass@host:1433/db?driver=theodbcdriver
, Parameterbeschreibung:
user
: Benutzernamepassword
: Passworthost
: Hostadresseport
: Port (Standard ist 1433)database
: Datenbanknamedriver
: ODBC-Treibername, der in der Dateiodbcinst.ini
konfiguriert werden muss
Datenbankerstellung und -initialisierung
from tortoise import Tortoise, run_async async def init(): # Verwenden Sie die SQLite-Datenbank, und der Dateiname ist db.sqlite3 # Und geben Sie den Anwendungsnamen mit dem Modell als "models" an await Tortoise.init( db_url='sqlite://db.sqlite3', modules={'models': ['models']} ) # Generieren Sie die Datenbanktabellenstruktur await Tortoise.generate_schemas() # safe-Parameter: Wenn auf True gesetzt, wird die Tabelle nur erstellt, wenn sie nicht existiert run_async(init()) # Kontext automatisch verarbeiten und die Datenbankverbindung nach Abschluss des Vorgangs schließen
Wenn Sie die MySQL-Datenbank verwenden, müssen Sie zuerst die Abhängigkeit tortoise-orm[aiomysql]
installieren.
Modelldefinition
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 # Ob es sich um eine abstrakte Klasse handelt, wenn True, wird keine Datentabelle generiert table = "team" # Tabellenname, wenn nicht festgelegt, wird standardmäßig der Klassenname verwendet table_description = "" # Tabellenkommentar unique_together = () # Zusammengesetzter eindeutiger Index indexes = () # Zusammengesetzter nicht eindeutiger Index ordering = [] # Standardsortierung manager = Manager # Benutzerdefinierter Manager
Feldtypen
Datenfelder
from tortoise import fields fields.Field( source_field=None, # Benutzerdefinierter Datenbankspaltenname generated=False, # Ob er automatisch von der Datenbank generiert wird pk=False, # Ob es sich um den Primärschlüssel handelt null=False, # Ob das Feld leer sein kann default=None, # Standardwert unique=False, # Ob der Wert eindeutig ist index=False, # Ob ein Index erstellt werden soll description=None, # Feldbeschreibung validators=None # Liste der Validatoren )
Beziehungsfelder
- Fremdschlüsselfeld
fields.ForeignKeyField( model_name, # Zugeordneter Modellname im Format {app}.{models} related_name=None, # Attributname für die umgekehrte Auflösung on_delete='CASCADE', # Löschstrategie, optionale Werte: CASCADE, RESTRICT, SET_NULL, SET_DEFAULT db_constraint=True, # Ob eine Fremdschlüsselbeschränkung in der Datenbank erstellt werden soll )
- Eins-zu-Eins-Feld
fields.OneToOneField( model_name, related_name=None, on_delete='CASCADE', db_constraint=True )
- Viele-zu-Viele-Feld
fields.ManyToManyField( model_name, through=None, # Zwischentabelle forward_key=None, # Vorwärtssuchschlüssel backward_key='', # Rückwärtssuchschlüssel related_name='', on_delete='CASCADE', db_constraint=True )
Abfrageoperationen
Das Modell bietet verschiedene Abfragemethoden:
filter(*args, **kwargs)
: Daten entsprechend den Bedingungen filternexclude(*args, **kwargs)
: Daten ausschließen, die die Bedingungen erfüllenall()
: Alle Daten abrufenfirst()
: Das erste Datenelement abrufenannotate()
: Aggregationsabfrage
Die von der filter
-Methode unterstützten Abfragebedingungen:
- Bereichsabfrage:
in
,not_in
,gte
,gt
,lte
,lt
,range
- Nullwertabfrage:
isnull
,not_isnull
- Zeichenkettenabfrage:
contains
,icontains
,startswith
,istartswith
,endswith
,iendswith
,iexact
- Volltextsuche:
search
Hier sind einige konkrete Abfragebeispiele:
Einfaches Abfragebeispiel
Angenommen, das Team
-Modell wurde definiert:
from tortoise import run_async from models import Team # Angenommen, das Modell ist in der Datei models.py definiert async def simple_query(): # Alle Team-Einträge abrufen all_teams = await Team.all() print("Alle Teams:", all_teams) # Den ersten Team-Eintrag abrufen first_team = await Team.first() print("Das erste Team:", first_team) # Filtern Sie gemäß der Bedingung und rufen Sie das Team ab, dessen Name "Team A" lautet filtered_teams = await Team.filter(name="Team A") print("Teams mit dem Namen Team A:", filtered_teams) run_async(simple_query())
Bereichsabfragebeispiel
from tortoise import run_async from models import Team async def range_query(): # Abfrageteams mit einer ID größer als 5 greater_than_5 = await Team.filter(id__gt=5) print("Teams mit einer ID größer als 5:", greater_than_5) # Abfrageteams mit einer ID zwischen 2 und 8 (einschließlich 2 und 8) in_range = await Team.filter(id__range=(2, 8)) print("Teams mit einer ID zwischen 2 und 8:", in_range) # Abfrageteams, deren ID nicht in [1, 3, 5] enthalten ist not_in_list = await Team.filter(id__not_in=[1, 3, 5]) print("Teams, deren ID nicht in [1, 3, 5] enthalten ist:", not_in_list) run_async(range_query())
Zeichenkettenabfragebeispiel
from tortoise import run_async from models import Team async def string_query(): # Abfrageteams, deren Name die Zeichenkette "team" enthält (Groß-/Kleinschreibung wird nicht beachtet) contains_team = await Team.filter(name__icontains="team") print("Teams, deren Name team enthält (Groß-/Kleinschreibung wird nicht beachtet):", contains_team) # Abfrageteams, deren Name mit "A" beginnt (Groß-/Kleinschreibung wird beachtet) startswith_A = await Team.filter(name__startswith="A") print("Teams, deren Name mit A beginnt:", startswith_A) # Abfrageteams, deren Name mit "B" endet (Groß-/Kleinschreibung wird nicht beachtet) endswith_B = await Team.filter(name__iendswith="B") print("Teams, deren Name mit B endet (Groß-/Kleinschreibung wird nicht beachtet):", endswith_B) run_async(string_query())
Für detailliertere Informationen lesen Sie bitte die Offizielle Tortoise ORM-Dokumentation.
Leapcell: Das Beste von Serverless Web Hosting
Schließlich möchte ich eine Plattform empfehlen, die sich am besten für die Bereitstellung von Python-Diensten eignet: Leapcell
🚀 Mit Ihrer Lieblingssprache entwickeln
Entwickeln Sie mühelos in JavaScript, Python, Go oder Rust.
🌍 Unbegrenzte Projekte kostenlos bereitstellen
Zahlen Sie nur für das, was Sie nutzen – keine Anfragen, keine Gebühren.
⚡ Pay-as-You-Go, keine versteckten Kosten
Keine Leerlaufgebühren, nur nahtlose Skalierbarkeit.
📖 Entdecken Sie unsere Dokumentation
🔹 Folgen Sie uns auf Twitter: @LeapcellHQ