模型

Models

使用方法

Usage

要开始使用模型,首先应该导入它们:

from tortoise.models import Model

有了这个,你可以开始描述自己的模型,如下所示:

class Tournament(Model):
    id = fields.IntField(primary_key=True)
    name = fields.TextField()
    created = fields.DatetimeField(auto_now_add=True)

    def __str__(self):
        return self.name


class Event(Model):
    id = fields.IntField(primary_key=True)
    name = fields.TextField()
    tournament = fields.ForeignKeyField('models.Tournament', related_name='events')
    participants = fields.ManyToManyField('models.Team', related_name='events', through='event_team')
    modified = fields.DatetimeField(auto_now=True)
    prize = fields.DecimalField(max_digits=10, decimal_places=2, null=True)

    def __str__(self):
        return self.name


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

    def __str__(self):
        return self.name

让我们详细看看我们在这里完成了什么:

class Tournament(Model):

每个模型都应该从基础模型派生。你也可以从自己的模型子类派生,并且可以像这样创建抽象模型:

class AbstractTournament(Model):
    id = fields.IntField(primary_key=True)
    name = fields.TextField()
    created = fields.DatetimeField(auto_now_add=True)

    class Meta:
        abstract = True

    def __str__(self):
        return self.name

这些模型不会在架构生成中被创建,也不会与其他模型建立关系。

进一步来看,我们有字段 fields.DatetimeField(auto_now=True)。选项 auto_nowauto_now_add 的工作方式类似于 Django 的选项。

To get working with models, first you should import them

from tortoise.models import Model

With that you can start describing your own models like that

class Tournament(Model):
    id = fields.IntField(primary_key=True)
    name = fields.TextField()
    created = fields.DatetimeField(auto_now_add=True)

    def __str__(self):
        return self.name


class Event(Model):
    id = fields.IntField(primary_key=True)
    name = fields.TextField()
    tournament = fields.ForeignKeyField('models.Tournament', related_name='events')
    participants = fields.ManyToManyField('models.Team', related_name='events', through='event_team')
    modified = fields.DatetimeField(auto_now=True)
    prize = fields.DecimalField(max_digits=10, decimal_places=2, null=True)

    def __str__(self):
        return self.name


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

    def __str__(self):
        return self.name

Let see in details what we accomplished here:

class Tournament(Model):

Every model should be derived from base model. You also can derive from your own model subclasses and you can make abstract models like this

class AbstractTournament(Model):
    id = fields.IntField(primary_key=True)
    name = fields.TextField()
    created = fields.DatetimeField(auto_now_add=True)

    class Meta:
        abstract = True

    def __str__(self):
        return self.name

This models won’t be created in schema generation and won’t create relations to other models.

Further we have field fields.DatetimeField(auto_now=True). Options auto_now and auto_now_add work like Django’s options.

__models__ 的用法

Use of __models__

如果在加载模型的模块中定义了变量 __models__,则 generate_schema 将使用该列表,而不是自动查找模型。

If you define the variable __models__ in the module which you load your models from, generate_schema will use that list, rather than automatically finding models for you.

主键

Primary Keys

在 Tortoise ORM 中,我们要求每个模型都有一个主键。

该主键可以通过一个保留字段 pk 访问,该字段是被指定为主键的字段的别名。这个别名字段可以在过滤时作为字段名称使用,例如 .filter(pk=...) 等等。

Note

我们当前支持任何可索引字段类型的单一(非组合)主键,但只推荐以下字段类型:

IntField
BigIntField
CharField
UUIDField

必须通过将 primary_key 参数设置为 True 来定义主键。如果不定义主键,我们将为您创建一个类型为 IntField 名称为 id 的主键。

如果在整数字段上使用此选项,则 generated 将设置为 True,除非您显式传递 generated=False

以下任何定义都是模型中有效的主键定义:

id = fields.IntField(primary_key=True)

checksum = fields.CharField(primary_key=True)

guid = fields.UUIDField(primary_key=True)

In Tortoise ORM we require that a model has a primary key.

That primary key will be accessible through a reserved field pk which will be an alias of whichever field has been nominated as a primary key. That alias field can be used as a field name when doing filtering e.g. .filter(pk=...) etc…

Note

We currently support single (non-composite) primary keys of any indexable field type, but only these field types are recommended:

IntField
BigIntField
CharField
UUIDField

One must define a primary key by setting a primary_key parameter to True. If you don’t define a primary key, we will create a primary key of type IntField with name of id for you.

If this is used on an Integer Field, generated will be set to True unless you explicitly pass generated=False as well.

Any of these are valid primary key definitions in a Model:

id = fields.IntField(primary_key=True)

checksum = fields.CharField(primary_key=True)

guid = fields.UUIDField(primary_key=True)

继承

Inheritance

在 Tortoise ORM 中定义模型时,可以通过利用继承来节省大量重复工作。

您可以在更通用的类中定义字段,这些字段会自动在派生类中可用。基类不限于模型类,任何类都可以使用。这样,您能够以自然且易于维护的方式定义模型。

让我们来看一些示例。

from tortoise import fields
from tortoise.models import Model

class TimestampMixin():
    created_at = fields.DatetimeField(null=True, auto_now_add=True)
    modified_at = fields.DatetimeField(null=True, auto_now=True)

class NameMixin():
    name = fields.CharField(40, unique=True)

class MyAbstractBaseModel(Model):
    id = fields.IntField(primary_key=True)

    class Meta:
        abstract = True

class UserModel(TimestampMixin, MyAbstractBaseModel):
    # 重写 MyAbstractBaseModel 的 id 定义
    id = fields.UUIDField(primary_key=True)

    # 添加额外字段
    first_name = fields.CharField(20, null=True)

    class Meta:
        table = "user"


class RoleModel(TimestampMixin, NameMixin, MyAbstractBaseModel):

    class Meta:
        table = "role"

使用 Meta 类不是必需的,但这是一个好习惯,可以为您的表提供一个明确的名称。这样,您可以在不破坏架构的情况下更改模型名称。因此,以下定义是有效的。

class RoleModel(TimestampMixin, NameMixin, MyAbstractBaseModel):

When defining models in Tortoise ORM, you can save a lot of repetitive work by leveraging from inheritance.

You can define fields in more generic classes and they are automatically available in derived classes. Base classes are not limited to Model classes. Any class will work. This way you are able to define your models in a natural and easy to maintain way.

Let’s have a look at some examples.

from tortoise import fields
from tortoise.models import Model

class TimestampMixin():
    created_at = fields.DatetimeField(null=True, auto_now_add=True)
    modified_at = fields.DatetimeField(null=True, auto_now=True)

class NameMixin():
    name = fields.CharField(40, unique=True)

class MyAbstractBaseModel(Model):
    id = fields.IntField(primary_key=True)

    class Meta:
        abstract = True

class UserModel(TimestampMixin, MyAbstractBaseModel):
    # Overriding the id definition
    # from MyAbstractBaseModel
    id = fields.UUIDField(primary_key=True)

    # Adding additional fields
    first_name = fields.CharField(20, null=True)

    class Meta:
        table = "user"


class RoleModel(TimestampMixin, NameMixin, MyAbstractBaseModel):

    class Meta:
        table = "role"

Using the Meta class is not necessary. But it is a good habit, to give your table an explicit name. This way you can change the model name without breaking the schema. So the following definition is valid.

class RoleModel(TimestampMixin, NameMixin, MyAbstractBaseModel):

pass

Meta类

The Meta class

class tortoise.models.Model.Meta

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"), )
abstract = False

设置为 True 表示这是一个抽象类。

schema = ""

设置此项以配置表所在的模式名称。

table = ""

设置此项以配置手动表名称,而不是生成的名称。

table_description = ""

设置此项以生成当前模型创建的表的注释信息。

unique_together = None

指定 unique_together 来为列集设置复合唯一索引。

它应该是一个元组的元组(列表也可以),格式如下:

unique_together=("field_a", "field_b")
unique_together=(("field_a", "field_b"), )
unique_together=(("field_a", "field_b"), ("field_c", "field_d", "field_e"))
indexes = None

指定 indexes 来为列集设置复合非唯一索引。

它应该是一个元组的元组(列表也可以),格式如下:

indexes=("field_a", "field_b")
indexes=(("field_a", "field_b"), )
indexes=(("field_a", "field_b"), ("field_c", "field_d", "field_e"))
ordering = None

指定 ordering 来为给定模型设置默认排序。 它应该是可迭代的字符串,格式与 .order_by(...) 接收的格式相同。 如果查询是使用 .annotate(...) 生成的 GROUP_BY 子句,则不应用默认排序。

ordering = ["name", "-score"]
manager = tortoise.manager.Manager

指定 manager 以覆盖默认管理器。 它应该是 tortoise.manager.Manager 或其子类的实例。

manager = CustomManager()
class tortoise.models.Model.Meta

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"), )
abstract = False

Set to True to indicate this is an abstract class

schema = ""

Set this to configure a schema name, where table exists

table = ""

Set this to configure a manual table name, instead of a generated one

table_description = ""

Set this to generate a comment message for the table being created for the current model

unique_together = None

Specify unique_together to set up compound unique indexes for sets of columns.

It should be a tuple of tuples (lists are fine) in the format of:

unique_together=("field_a", "field_b")
unique_together=(("field_a", "field_b"), )
unique_together=(("field_a", "field_b"), ("field_c", "field_d", "field_e"))
indexes = None

Specify indexes to set up compound non-unique indexes for sets of columns.

It should be a tuple of tuples (lists are fine) in the format of:

indexes=("field_a", "field_b")
indexes=(("field_a", "field_b"), )
indexes=(("field_a", "field_b"), ("field_c", "field_d", "field_e"))
ordering = None

Specify ordering to set up default ordering for given model. It should be iterable of strings formatted in same way as .order_by(...) receives. If query is built with GROUP_BY clause using .annotate(...) default ordering is not applied.

ordering = ["name", "-score"]
manager = tortoise.manager.Manager

Specify manager to override the default manager. It should be instance of tortoise.manager.Manager or subclass.

manager = CustomManager()

外键

ForeignKeyField

tournament = fields.ForeignKeyField('models.Tournament', related_name='events')
participants = fields.ManyToManyField('models.Team', related_name='events')
modified = fields.DatetimeField(auto_now=True)
prize = fields.DecimalField(max_digits=10, decimal_places=2, null=True)

在事件模型中,我们添加了一些可能对我们有趣的字段。

fields.ForeignKeyField('models.Tournament', related_name='events')

在这里,我们创建了一个指向锦标赛的外键引用。通过引用模型的字面量(由应用名称和模型名称组成)来创建。models 是默认的应用名称,但可以在 class Meta 中使用 app = 'other' 来更改。

related_name

是一个关键字参数,定义了对被引用模型的相关查询字段,因此你可以像这样获取所有锦标赛的事件:

await Tournament.first().prefetch_related("events")
tournament = fields.ForeignKeyField('models.Tournament', related_name='events')
participants = fields.ManyToManyField('models.Team', related_name='events')
modified = fields.DatetimeField(auto_now=True)
prize = fields.DecimalField(max_digits=10, decimal_places=2, null=True)

In event model we got some more fields, that could be interesting for us.

fields.ForeignKeyField('models.Tournament', related_name='events')

Here we create foreign key reference to tournament. We create it by referring to model by it’s literal, consisting of app name and model name. models is default app name, but you can change it in class Meta with app = 'other'.

related_name

Is keyword argument, that defines field for related query on referenced models, so with that you could fetch all tournaments’s events with like this:

await Tournament.first().prefetch_related("events")

数据库字段

The DB-backing field

Note

ForeignKeyField 是一个虚拟字段,这意味着它没有直接的数据库支持。 相反,它有一个字段(默认名为 FKNAME_id`(即只附加 ``_id`)), 这是实际的数据库支持字段。

它只会包含相关表的键值。

这是一个重要细节,因为这允许直接分配/读取实际值, 如果不需要整个外部对象,这可以被视为一种优化。

指定外键可以通过传递对象完成:

await SomeModel.create(tournament=the_tournament)
# 或者
somemodel.tournament=the_tournament

或者通过直接访问数据库支持字段:

await SomeModel.create(tournament_id=the_tournament.pk)
# 或者
somemodel.tournament_id=the_tournament.pk

查询关系通常通过追加双下划线,然后是外部对象的字段来完成。然后可以追加一个普通查询属性。 如果下一个键也是一个外部对象,则可以链接:

FKNAME__FOREIGNFIELD__gt=3

FKNAME__FOREIGNFK__VERYFOREIGNFIELD__gt=3

然而,有一个主要的限制。我们不想限制外部列名称,或产生歧义(例如,一个外部对象可能有一个字段叫 isnull)。

那么这将是完全模糊的:

FKNAME__isnull

为了防止这种情况,我们要求直接过滤器应用于外键的数据库支持字段:

FKNAME_id__isnull

Note

A ForeignKeyField is a virtual field, meaning it has no direct DB backing. Instead it has a field (by default called FKNAME_id (that is, just an _id is appended) that is the actual DB-backing field.

It will just contain the Key value of the related table.

This is an important detail as it would allow one to assign/read the actual value directly, which could be considered an optimization if the entire foreign object isn’t needed.

Specifying an FK can be done via either passing the object:

await SomeModel.create(tournament=the_tournament)
# or
somemodel.tournament=the_tournament

or by directly accessing the DB-backing field:

await SomeModel.create(tournament_id=the_tournament.pk)
# or
somemodel.tournament_id=the_tournament.pk

Querying a relationship is typically done by appending a double underscore, and then the foreign object’s field. Then a normal query attr can be appended. This can be chained if the next key is also a foreign object:

FKNAME__FOREIGNFIELD__gt=3

or

FKNAME__FOREIGNFK__VERYFOREIGNFIELD__gt=3

There is however one major limitation. We don’t want to restrict foreign column names, or have ambiguity (e.g. a foreign object may have a field called isnull)

Then this would be entirely ambiguous:

FKNAME__isnull

To prevent that we require that direct filters be applied to the DB-backing field of the foreign key:

FKNAME_id__isnull

获取外键对象

Fetching the foreign object

获取外键可以通过异步和同步接口进行。

异步获取:

events = await tournament.events.all()

你可以像这样异步迭代它:

async for event in tournament.events:
    ...

同步使用要求你在使用之前调用 fetch_related,然后你可以使用常见的函数,例如:

await tournament.fetch_related('events')
events = list(tournament.events)
eventlen = len(tournament.events)
if SomeEvent in tournament.events:
    ...
if tournament.events:
    ...
firstevent = tournament.events[0]

要获取反向外键,例如 event.tournament,我们目前只支持同步接口。

await event.fetch_related('tournament')
tournament = event.tournament

Fetching foreign keys can be done with both async and sync interfaces.

Async fetch:

events = await tournament.events.all()

You can async iterate over it like this:

async for event in tournament.events:
    ...

Sync usage requires that you call fetch_related before the time, and then you can use common functions such as:

await tournament.fetch_related('events')
events = list(tournament.events)
eventlen = len(tournament.events)
if SomeEvent in tournament.events:
    ...
if tournament.events:
    ...
firstevent = tournament.events[0]

To get the Reverse-FK, e.g. an event.tournament we currently only support the sync interface.

await event.fetch_related('tournament')
tournament = event.tournament

多对多关系

ManyToManyField

下一个字段是 fields.ManyToManyField('models.Team', related_name='events')。它描述了与 Team 模型的多对多关系。

要向 ManyToManyField 添加关系,两个模型都需要被保存,否则会引发 OperationalError

解析多对多字段可以通过异步和同步接口进行。

异步获取:

participants = await tournament.participants.all()

你可以像这样异步迭代它:

async for participant in tournament.participants:
    ...

同步使用要求你在使用之前调用 fetch_related ,然后你可以使用常见的函数,例如:

await tournament.fetch_related('participants')
participants = list(tournament.participants)
participantlen = len(tournament.participants)
if SomeParticipant in tournament.participants:
    ...
if tournament.participants:
    ...
firstparticipant = tournament.participants[0]

team.event_team 的反向查找工作方式完全相同。

Next field is fields.ManyToManyField('models.Team', related_name='events'). It describes many to many relation to model Team.

To add to a ManyToManyField both the models need to be saved, else you will get an OperationalError raised.

Resolving many to many fields can be done with both async and sync interfaces.

Async fetch:

participants = await tournament.participants.all()

You can async iterate over it like this:

async for participant in tournament.participants:
    ...

Sync usage requires that you call fetch_related before the time, and then you can use common functions such as:

await tournament.fetch_related('participants')
participants = list(tournament.participants)
participantlen = len(tournament.participants)
if SomeParticipant in tournament.participants:
    ...
if tournament.participants:
    ...
firstparticipant = tournament.participants[0]

The reverse lookup of team.event_team works exactly the same way.

改进关系类型提示

Improving relational type hinting

由于 Tortoise ORM 仍然是一个年轻的项目,它在各种编辑器中的支持并不广泛,这些编辑器可以帮助你编写代码并提供良好的模型和不同关系的自动完成(自动提示)功能。然而,通过一些小的工作,你可以获得这样的自动补全。你需要做的就是为负责关系的字段向模型添加一些注解。

下面是来自 开始入门 的更新示例,它将为所有模型添加自动完成(自动提示)功能,包括模型之间关系的字段。

from tortoise.models import Model
from tortoise import fields


class Tournament(Model):
    id = fields.IntField(primary_key=True)
    name = fields.CharField(max_length=255)

    events: fields.ReverseRelation["Event"]

    def __str__(self):
        return self.name


class Event(Model):
    id = fields.IntField(primary_key=True)
    name = fields.CharField(max_length=255)
    tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField(
        "models.Tournament", related_name="events"
    )
    participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
        "models.Team", related_name="events", through="event_team"
    )

    def __str__(self):
        return self.name


class Team(Model):
    id = fields.IntField(primary_key=True)
    name = fields.CharField(max_length=255)

    events: fields.ManyToManyRelation[Event]

    def __str__(self):
        return self.name

Since Tortoise ORM is still a young project, it does not have such widespread support by various editors who help you writing code using good autocomplete for models and different relations between them. However, you can get such autocomplete by doing a little work yourself. All you need to do is add a few annotations to your models for fields that are responsible for the relations.

Here is an updated example from 开始入门, that will add autocomplete for all models including fields for the relations between models.

from tortoise.models import Model
from tortoise import fields


class Tournament(Model):
    id = fields.IntField(primary_key=True)
    name = fields.CharField(max_length=255)

    events: fields.ReverseRelation["Event"]

    def __str__(self):
        return self.name


class Event(Model):
    id = fields.IntField(primary_key=True)
    name = fields.CharField(max_length=255)
    tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField(
        "models.Tournament", related_name="events"
    )
    participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
        "models.Team", related_name="events", through="event_team"
    )

    def __str__(self):
        return self.name


class Team(Model):
    id = fields.IntField(primary_key=True)
    name = fields.CharField(max_length=255)

    events: fields.ManyToManyRelation[Event]

    def __str__(self):
        return self.name

参考

Reference

class tortoise.models.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 all(using_db=None)[source]

Returns the complete QuerySet.

Return type:

QuerySet[Self]

classmethod annotate(**kwargs)[source]

Annotates the result set with extra Functions/Aggregations/Expressions.

Parameters:
**kwargs

Parameter name and the Function/Aggregation to annotate with.

Return type:

QuerySet[Self]

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

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'])
Parameters:
objects

List of objects to bulk create

fields

The fields to update

batch_size=None

How many objects are created in a single query

using_db=None

Specific DB connection to use instead of default bound

Return type:

BulkUpdateQuery[Model]

clone(pk=<object object>)[source]

Create a new clone of the object that when you do a .save() will create a new record.

Parameters:
pk : Any

An optionally required value if the model doesn’t generate its own primary key. Any value you specify here will always be used.

Return type:

Model

Returns:

A copy of the current object without primary key information.

Raises:

ParamsError – If pk is required but not provided.

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()
Parameters:
using_db=None

Specific DB connection to use instead of default bound

**kwargs

Model parameters.

Return type:

Model

async delete(using_db=None)[source]

Deletes the current model object.

Parameters:
using_db=None

Specific DB connection to use instead of default bound

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 to True)

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 exclude(*args, **kwargs)[source]

Generates a QuerySet with the exclude applied.

Parameters:
*args

Q functions containing constraints. Will be AND’ed.

**kwargs

Simple filter constraints.

Return type:

QuerySet[Self]

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")
Parameters:
using_db=None

The specific DB connection to use.

*args

Q functions containing constraints. Will be AND’ed.

**kwargs

Simple filter constraints.

Return type:

ExistsQuery

async classmethod fetch_for_list(instance_list, *args, using_db=None)[source]

Fetches related models for provided list of Model objects.

Parameters:
instance_list

List of Model objects to fetch relations for.

*args

Relation names to fetch.

using_db=None

DO NOT USE

Return type:

None

Fetch related fields.

User.fetch_related("emails", "manager")
*args

The related fields that should be fetched.

using_db=None

Specific DB connection to use instead of default bound

None

classmethod filter(*args, **kwargs)[source]

Generates a QuerySet with the filter applied.

Parameters:
*args

Q functions containing constraints. Will be AND’ed.

**kwargs

Simple filter constraints.

Return type:

QuerySet[Self]

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:
using_db=None

The DB connection to use

*args

Q functions containing constraints. Will be AND’ed.

**kwargs

Simple filter constraints.

Raises:
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:
defaults=None

Default values to be added to a created instance if it can’t be fetched.

using_db=None

Specific DB connection to use instead of default bound

**kwargs

Query parameters.

Raises:
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")
Parameters:
using_db=None

The specific DB connection to use.

*args

Q functions containing constraints. Will be AND’ed.

**kwargs

Simple filter constraints.

Return type:

QuerySetSingle[Optional[Self]]

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.

Parameters:
id_list

A list of field values

field_name='pk'

Must be a unique field

using_db=None

Specific DB connection to use instead of default bound

Return type:

Dict[str, Model]

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%'")
Parameters:
using_db=None

The specific DB connection to use

sql

The raw sql.

Return type:

RawSQLQuery

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'])
Parameters:
fields=None

The special fields that to be refreshed.

using_db=None

Specific DB connection to use instead of default bound.

Raises:

OperationalError – If object has never been persisted.

Return type:

None

classmethod register_listener(signal, listener)[source]

Register listener to current model class for special Signal.

Parameters:
signal

one of tortoise.signals.Signals

listener

callable listener

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

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.

Return type:

QuerySet[Self]

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:

Model

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

async classmethod update_or_create(defaults=None, using_db=None, **kwargs)[source]

A convenience method for updating an object with the given kwargs, creating a new one if necessary.

Parameters:
defaults=None

Default values used to update the object.

using_db=None

Specific DB connection to use instead of default bound

**kwargs

Query parameters.

Return type:

Tuple[Model, bool]