Leapcell: The Best of Serverless Web Hosting
Tortoise ORM: A Powerful Object Relational Mapper Based on asyncio
Tortoise ORM is an easy-to-use asyncio ORM (Object Relational Mapper) for Python, inspired by Django ORM. It borrows the design concept of Django ORM. It not only supports the processing of traditional tabular data but also can efficiently manage relational data. In terms of performance, it is not inferior to other Python ORMs.
Supported Databases
Tortoise ORM currently supports multiple mainstream databases:
- SQLite: Driven by
aiosqlite
, suitable for lightweight application scenarios. - PostgreSQL: The version should be >= 9.4, supporting
asyncpg
(asynchronous mode) orpsycopg
(synchronous mode) drivers. - MySQL/MariaDB: Achieves efficient connection with the help of the
asyncmy
driver. - Microsoft SQL Server: Completes data interaction through the
asyncodbc
driver.
Environment Configuration and Installation
- Install Tortoise ORM
pip install tortoise-orm
-
Install the corresponding database driver
- PostgreSQL (Asynchronous):
pip install tortoise-orm[asyncpg]
- **MySQL/MariaDB**:
```bash
pip install tortoise-orm[asyncmy]
```
- **SQLite**: Supported by default, no additional driver installation is required
Database Connection Configuration
SQLite
The connection string format is sqlite://DB_FILE
. For example, if the database file is /data/DB.sqlite3
, the complete connection string is sqlite:///data/db.sqlite3
(note the three slashes).
MySQL
The connection string format: mysql://user:password@host:3306/somedb
, parameter description:
user
: Database usernamepassword
: User passwordhost
: Database host addressport
: Database port (default is 3306)database
: The name of the database to connect to
PostgreSQL
- Asynchronous mode:
asyncpg://postgres:pass@db.host:5432/somedb
- Synchronous mode:
psycopg://postgres:pass@db.host:5432/somedb
Microsoft SQL Server
The connection string format: mssql://user:pass@host:1433/db?driver=theodbcdriver
, parameter description:
user
: Usernamepassword
: Passwordhost
: Host addressport
: Port (default is 1433)database
: Database namedriver
: ODBC driver name, which needs to be configured in theodbcinst.ini
file
Database Creation and Initialization
from tortoise import Tortoise, run_async
async def init():
# Use the SQLite database, and the file name is db.sqlite3
# And specify the application name containing the model as "models"
await Tortoise.init(
db_url='sqlite://db.sqlite3',
modules={'models': ['models']}
)
# Generate the database table structure
await Tortoise.generate_schemas() # safe parameter: When set to True, the table will only be created if it does not exist
run_async(init()) # Automatically handle the context and close the database connection after the operation ends
If using the MySQL database, you need to install the tortoise-orm[aiomysql]
dependency first.
Model Definition
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 # Whether it is an abstract class, if True, no data table will be generated
table = "team" # Table name, if not set, the class name will be used by default
table_description = "" # Table comment
unique_together = () # Composite unique index
indexes = () # Composite non-unique index
ordering = [] # Default sorting
manager = Manager # Custom manager
Field Types
Data Fields
from tortoise import fields
fields.Field(
source_field=None, # Custom database column name
generated=False, # Whether it is automatically generated by the database
pk=False, # Whether it is the primary key
null=False, # Whether the field can be empty
default=None, # Default value
unique=False, # Whether the value is unique
index=False, # Whether to create an index
description=None, # Field description
validators=None # List of validators
)
Relationship Fields
- Foreign Key Field
fields.ForeignKeyField(
model_name, # Associated model name, in the format of {app}.{models}
related_name=None, # Reverse resolution attribute name
on_delete='CASCADE', # Deletion strategy, optional values: CASCADE, RESTRICT, SET_NULL, SET_DEFAULT
db_constraint=True, # Whether to create a foreign key constraint in the database
)
- One-to-One Field
fields.OneToOneField(
model_name,
related_name=None,
on_delete='CASCADE',
db_constraint=True
)
- Many-to-Many Field
fields.ManyToManyField(
model_name,
through=None, # Intermediate table
forward_key=None, # Forward lookup key
backward_key='', # Reverse lookup key
related_name='',
on_delete='CASCADE',
db_constraint=True
)
Query Operations
The model provides multiple query methods:
filter(*args, **kwargs)
: Filter data according to conditionsexclude(*args, **kwargs)
: Exclude data that meets the conditionsall()
: Get all datafirst()
: Get the first piece of dataannotate()
: Aggregate query
The query conditions supported by the filter
method:
- Range query:
in
,not_in
,gte
,gt
,lte
,lt
,range
- Null value query:
isnull
,not_isnull
- String query:
contains
,icontains
,startswith
,istartswith
,endswith
,iendswith
,iexact
- Full-text search:
search
Here are some specific query examples:
Simple Query Example
Suppose the Team
model has been defined:
from tortoise import run_async
from models import Team # Assume the model is defined in the models.py file
async def simple_query():
# Get all Team records
all_teams = await Team.all()
print("All teams:", all_teams)
# Get the first Team record
first_team = await Team.first()
print("The first team:", first_team)
# Filter according to the condition and get the team whose name is "Team A"
filtered_teams = await Team.filter(name="Team A")
print("Teams named Team A:", filtered_teams)
run_async(simple_query())
Range Query Example
from tortoise import run_async
from models import Team
async def range_query():
# Query teams with id greater than 5
greater_than_5 = await Team.filter(id__gt=5)
print("Teams with id greater than 5:", greater_than_5)
# Query teams with id between 2 and 8 (including 2 and 8)
in_range = await Team.filter(id__range=(2, 8))
print("Teams with id between 2 and 8:", in_range)
# Query teams whose id is not in [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())
String Query Example
from tortoise import run_async
from models import Team
async def string_query():
# Query teams whose name contains the string "team" (case-insensitive)
contains_team = await Team.filter(name__icontains="team")
print("Teams whose name contains team (case-insensitive):", contains_team)
# Query teams whose name starts with "A" (case-sensitive)
startswith_A = await Team.filter(name__startswith="A")
print("Teams whose name starts with A:", startswith_A)
# Query teams whose name ends with "B" (case-insensitive)
endswith_B = await Team.filter(name__iendswith="B")
print("Teams whose name ends with B (case-insensitive):", endswith_B)
run_async(string_query())
For more detailed usage, please refer to the Tortoise ORM Official Documentation.
Leapcell: The Best of Serverless Web Hosting
Finally, I would like to recommend a platform that is most suitable for deploying Python services: Leapcell
🚀 Build with Your Favorite Language
Develop effortlessly in JavaScript, Python, Go, or Rust.
🌍 Deploy Unlimited Projects for Free
Only pay for what you use—no requests, no charges.
⚡ Pay-as-You-Go, No Hidden Costs
No idle fees, just seamless scalability.
🔹 Follow us on Twitter: @LeapcellHQ
Tidak ada komentar:
Posting Komentar