启动¶
Set up
初始化app¶
Init app
在您定义所有模型后,Tortoise 需要您初始化它们,以便创建模型之间的反向关系,并将您的数据库客户端与相应的模型匹配。
您可以这样做:
from tortoise import Tortoise
async def init():
# 在这里我们使用文件 "db.sqlite3" 创建一个 SQLite 数据库
# 同时指定应用名称为 "models"
# 其中包含来自 "app.models" 的模型
await Tortoise.init(
db_url='sqlite://db.sqlite3',
modules={'models': ['app.models']}
)
# 生成模式
await Tortoise.generate_schemas()
在这里,我们创建一个 SQLite 数据库客户端的连接,然后发现并初始化模型。
generate_schema
在空数据库上生成模式,您不应该在每次应用初始化时运行它,可能只需运行一次,最好在主代码之外。
在生成模式时,您还可以选择将 safe
参数设置为 True
,这将仅在表不存在时插入表。
如果您在 app.models
模块中定义变量 __models__
(或在您指定加载模型的其他地方), generate_schema
将使用该列表,而不是自动为您查找模型。
After you defined all your models, tortoise needs you to init them, in order to create backward relations between models and match your db client with appropriate models.
You can do it like this:
from tortoise import Tortoise
async def init():
# Here we create a SQLite DB using file "db.sqlite3"
# also specify the app name of "models"
# which contain models from "app.models"
await Tortoise.init(
db_url='sqlite://db.sqlite3',
modules={'models': ['app.models']}
)
# Generate the schema
await Tortoise.generate_schemas()
Here we create connection to SQLite database client and then we discover & initialize models.
generate_schema
generates schema on empty database, you shouldn’t run it on every app init, run it just once, maybe out of your main code.
There is also the option when generating the schemas to set the safe
parameter to True
which will only insert the tables if they don’t already exist.
If you define the variable __models__
in the app.models
module (or wherever you specify to load your models from), generate_schema
will use that list, rather than automatically finding models for you.
清理的重要性¶
The Importance of cleaning up
Tortoise ORM 将保持与外部数据库的连接。作为一个 asyncio
Python 库,它需要正确关闭连接,否则 Python 解释器可能仍会等待这些连接的完成。
为确保连接被关闭,请确保调用 Tortoise.close_connections()
:
await Tortoise.close_connections()
小帮助函数 tortoise.run_async()
将确保连接被关闭。
Tortoise ORM will keep connections open to external Databases. As an asyncio
Python library, it needs to have the connections closed properly or the Python interpreter may still wait for the completion of said connections.
To ensure connections are closed please ensure that Tortoise.close_connections()
is called:
await Tortoise.close_connections()
The small helper function tortoise.run_async()
will ensure that connections are closed.
参考¶
Reference
-
class tortoise.BaseDBAsyncClient(connection_name, fetch_inserted=
True
, **kwargs)[source]¶ Base class for containing a DB connection.
Parameters get passed as kwargs, and is mostly driver specific.
- query_class Type[pypika.Query]¶
The PyPika Query dialect (low level dialect)
- executor_class Type[BaseExecutor]¶
The executor dialect class (high level dialect)
- schema_generator Type[BaseSchemaGenerator]¶
The DDL schema generator
- capabilities Capabilities¶
Contains the connection capabilities
- acquire_connection()[source]¶
Acquires a connection from the pool. Will return the current context connection if already in a transaction.
- Return type:¶
Union
[ConnectionWrapper
[~T_conn],PoolConnectionWrapper
[~T_conn]]
-
capabilities : Capabilities =
<tortoise.backends.base.client.Capabilities object>
¶
- async db_create()[source]¶
Created the database in the server. Typically only called by the test runner.
Need to have called
create_connection()`
with parameterwith_db=False
set to use the default connection instead of the configured one, else you would get errors indicating the database doesn’t exist.- Return type:¶
None
- async db_delete()[source]¶
Delete the database from the Server. Typically only called by the test runner.
Need to have called
create_connection()`
with parameterwith_db=False
set to use the default connection instead of the configured one, else you would get errors indicating the database is in use.- Return type:¶
None
- async execute_insert(query, values)[source]¶
Executes a RAW SQL insert statement, with provided parameters.
- async execute_many(query, values)[source]¶
Executes a RAW bulk insert statement, like execute_insert, but returns no data.
-
async execute_query(query, values=
None
)[source]¶ Executes a RAW SQL query statement, and returns the resultset.
-
async execute_query_dict(query, values=
None
)[source]¶ Executes a RAW SQL query statement, and returns the resultset as a list of dicts.
- async execute_script(query)[source]¶
Executes a RAW SQL script with multiple statements, and returns nothing.
- executor_class¶
alias of
BaseExecutor
- query_class¶
alias of
Query
- schema_generator¶
alias of
BaseSchemaGenerator
- class tortoise.Model(**kwargs)[source]¶
Base class for all Tortoise ORM Models.
- class Meta[source]¶
The
Meta
class is used to configure metadata for the Model.Usage:
class Foo(Model): ... class Meta: table="custom_table" unique_together=(("field_a", "field_b"), )
- classmethod annotate(**kwargs)[source]¶
Annotates the result set with extra Functions/Aggregations/Expressions.
-
classmethod bulk_create(objects, batch_size=
None
, ignore_conflicts=False
, update_fields=None
, on_conflict=None
, using_db=None
)[source]¶ Bulk insert operation:
Note
The bulk insert operation will do the minimum to ensure that the object created in the DB has all the defaults and generated fields set, but may be incomplete reference in Python.
e.g.
IntField
primary keys will not be populated.This is recommended only for throw away inserts where you want to ensure optimal insert performance.
User.bulk_create([ User(name="...", email="..."), User(name="...", email="...") ])
- Parameters:¶
- on_conflict=
None
¶ On conflict index name
- update_fields=
None
¶ Update fields when conflicts
- ignore_conflicts=
False
¶ Ignore conflicts when inserting
- objects¶
List of objects to bulk create
- batch_size=
None
¶ How many objects are created in a single query
- using_db=
None
¶ Specific DB connection to use instead of default bound
- on_conflict=
- Return type:¶
BulkCreateQuery
[Model]
-
classmethod bulk_update(objects, fields, batch_size=
None
, using_db=None
)[source]¶ Update the given fields in each of the given objects in the database. This method efficiently updates the given fields on the provided model instances, generally with one query.
users = [ await User.create(name="...", email="..."), await User.create(name="...", email="...") ] users[0].name = 'name1' users[1].name = 'name2' await User.bulk_update(users, fields=['name'])
- clone(pk=<object object>)[source]¶
Create a new clone of the object that when you do a
.save()
will create a new record.
-
async classmethod create(using_db=
None
, **kwargs)[source]¶ Create a record in the DB and returns the object.
user = await User.create(name="...", email="...")
Equivalent to:
user = User(name="...", email="...") await user.save()
-
async delete(using_db=
None
)[source]¶ Deletes the current model object.
- Parameters:¶
- using_db=
None
¶ Specific DB connection to use instead of default bound
- using_db=
- Raises:¶
OperationalError – If object has never been persisted.
- Return type:¶
None
-
classmethod describe(serializable=
True
)[source]¶ Describes the given list of models or ALL registered models.
- Parameters:¶
- serializable=
True
¶ False
if you want raw python objects,True
for JSON-serializable data. (Defaults toTrue
)
- serializable=
- Return type:¶
dict
- Returns:¶
A dictionary containing the model description.
The base dict has a fixed set of keys that reference a list of fields (or a single field in the case of the primary key):
{ "name": str # Qualified model name "app": str # 'App' namespace "table": str # DB table name "abstract": bool # Is the model Abstract? "description": str # Description of table (nullable) "docstring": str # Model docstring (nullable) "unique_together": [...] # List of List containing field names that # are unique together "pk_field": {...} # Primary key field "data_fields": [...] # Data fields "fk_fields": [...] # Foreign Key fields FROM this model "backward_fk_fields": [...] # Foreign Key fields TO this model "o2o_fields": [...] # OneToOne fields FROM this model "backward_o2o_fields": [...] # OneToOne fields TO this model "m2m_fields": [...] # Many-to-Many fields }
Each field is specified as defined in
tortoise.fields.base.Field.describe()
-
classmethod exists(*args, using_db=
None
, **kwargs)[source]¶ Return True/False whether record exists with the provided filter parameters.
result = await User.exists(username="foo")
-
async classmethod fetch_for_list(instance_list, *args, using_db=
None
)[source]¶ Fetches related models for provided list of Model objects.
Fetch related fields.
User.fetch_related("emails", "manager")
The related fields that should be fetched.
Specific DB connection to use instead of default bound
None
-
classmethod first(using_db=
None
)[source]¶ Generates a QuerySet that returns the first record.
- Return type:¶
QuerySetSingle
[Optional
[Self
]]
-
classmethod get(*args, using_db=
None
, **kwargs)[source]¶ Fetches a single record for a Model type using the provided filter parameters.
user = await User.get(username="foo")
- Parameters:¶
- Raises:¶
MultipleObjectsReturned – If provided search returned more than one object.
DoesNotExist – If object can not be found.
- Return type:¶
QuerySetSingle
[Self
]
-
async classmethod get_or_create(defaults=
None
, using_db=None
, **kwargs)[source]¶ Fetches the object if exists (filtering on the provided parameters), else creates an instance with any unspecified parameters as default values.
- Parameters:¶
- Raises:¶
IntegrityError – If create failed
TransactionManagementError – If transaction error
ParamsError – If defaults conflict with kwargs
- Return type:¶
Tuple
[Self
,bool
]
-
classmethod get_or_none(*args, using_db=
None
, **kwargs)[source]¶ Fetches a single record for a Model type using the provided filter parameters or None.
user = await User.get_or_none(username="foo")
-
async classmethod in_bulk(id_list, field_name=
'pk'
, using_db=None
)[source]¶ Return a dictionary mapping each of the given IDs to the object with that ID. If id_list isn’t provided, evaluate the entire QuerySet.
- property pk : Any¶
Alias to the models Primary Key. Can be used as a field name when doing filtering e.g.
.filter(pk=...)
etc…- Return type:¶
Any
-
classmethod raw(sql, using_db=
None
)[source]¶ Executes a RAW SQL and returns the result
result = await User.raw("select * from users where name like '%test%'")
-
async refresh_from_db(fields=
None
, using_db=None
)[source]¶ Refresh latest data from db. When this method is called without arguments all db fields of the model are updated to the values currently present in the database.
user.refresh_from_db(fields=['name'])
- classmethod register_listener(signal, listener)[source]¶
Register listener to current model class for special Signal.
- Parameters:¶
- Raises:¶
ConfigurationError – When listener is not callable
-
async save(using_db=
None
, update_fields=None
, force_create=False
, force_update=False
)[source]¶ Creates/Updates the current model object.
- Parameters:¶
- update_fields=
None
¶ If provided, it should be a tuple/list of fields by name.
This is the subset of fields that should be updated. If the object needs to be created
update_fields
will be ignored.- using_db=
None
¶ Specific DB connection to use instead of default bound
- force_create=
False
¶ Forces creation of the record
- force_update=
False
¶ Forces updating of the record
- update_fields=
- Raises:¶
IncompleteInstanceError – If the model is partial and the fields are not available for persistence.
IntegrityError – If the model can’t be created or updated (specifically if force_create or force_update has been set)
- Return type:¶
None
-
classmethod select_for_update(nowait=
False
, skip_locked=False
, of=()
, using_db=None
)[source]¶ Make QuerySet select for update.
Returns a queryset that will lock rows until the end of the transaction, generating a SELECT … FOR UPDATE SQL statement on supported databases.
- update_from_dict(data)[source]¶
Updates the current model with the provided dict. This can allow mass-updating a model from a dict, also ensuring that datatype conversions happen.
This will ignore any extra fields, and NOT update the model with them, but will raise errors on bad types or updating Many-instance relations.
- Parameters:¶
- data¶
The parameters you want to update in a dict format
- Return type:¶
- Returns:¶
The current model instance
- Raises:¶
ConfigurationError – When attempting to update a remote instance (e.g. a reverse ForeignKey or ManyToMany relation)
ValueError – When a passed parameter is not type compatible
- class tortoise.Tortoise[source]¶
-
- async classmethod close_connections()[source]¶
Close all connections cleanly.
It is required for this to be called on exit, else your event loop may never complete as it is waiting for the connections to die.
Warning
This is deprecated and will be removed in a future release. Please use
connections.close_all
instead.- Return type:¶
None
-
classmethod describe_model(model, serializable=
True
)[source]¶ Describes the given list of models or ALL registered models.
- Parameters:¶
See
tortoise.models.Model.describe()
Warning
This is deprecated, please use
tortoise.models.Model.describe()
instead- Return type:¶
dict
-
classmethod describe_models(models=
None
, serializable=True
)[source]¶ Describes the given list of models or ALL registered models.
-
async classmethod generate_schemas(safe=
True
)[source]¶ Generate schemas according to models provided to
.init()
method. Will fail if schemas already exists, so it’s not recommended to be used as part of application workflow- Parameters:¶
- safe=
True
¶ When set to true, creates the table only when it does not already exist.
- safe=
- Raises:¶
ConfigurationError – When
.init()
has not been called.- Return type:¶
None
- classmethod get_connection(connection_name)[source]¶
Returns the connection by name.
- Raises:¶
ConfigurationError – If connection name does not exist.
Warning
This is deprecated and will be removed in a future release. Please use
connections.get
instead.- Return type:¶
-
async classmethod init(config=
None
, config_file=None
, _create_db=False
, db_url=None
, modules=None
, use_tz=False
, timezone='UTC'
, routers=None
)[source]¶ Sets up Tortoise-ORM.
You can configure using only one of
config
,config_file
and(db_url, modules)
.- Parameters:¶
- config=
None
¶ Dict containing config:
Example
{ 'connections': { # Dict format for connection 'default': { 'engine': 'tortoise.backends.asyncpg', 'credentials': { 'host': 'localhost', 'port': '5432', 'user': 'tortoise', 'password': 'qwerty123', 'database': 'test', } }, # Using a DB_URL string 'default': 'postgres://postgres:qwerty123@localhost:5432/test' }, 'apps': { 'my_app': { 'models': ['__main__'], # If no default_connection specified, defaults to 'default' 'default_connection': 'default', } }, 'routers': ['path.router1', 'path.router2'], 'use_tz': False, 'timezone': 'UTC' }
- config_file=
None
¶ Path to .json or .yml (if PyYAML installed) file containing config with same format as above.
- db_url=
None
¶ Use a DB_URL string. See DB_URL
- modules=
None
¶ Dictionary of
key
: [list_of_modules
] that defined “apps” and modules that should be discovered for models.- _create_db=
False
¶ If
True
tries to create database for specified connections, could be used for testing purposes.- use_tz=
False
¶ A boolean that specifies if datetime will be timezone-aware by default or not.
- timezone=
'UTC'
¶ Timezone to use, default is UTC.
- routers=
None
¶ A list of db routers str path or module.
- config=
- Raises:¶
ConfigurationError – For any configuration error
- Return type:¶
None
-
classmethod init_models(models_paths, app_label, _init_relations=
True
)[source]¶ Early initialisation of Tortoise ORM Models.
Initialise the relationships between Models. This does not initialise any database connection.