Модель:
Определение модели
Определяя модель ormar, вы получите бесплатную модель Pydantic и таблицу Sqlalchemy. Они управляются в фоновом режиме, и вам не нужно создавать их самостоятельно.
классы моделей
Чтобы построить модель ormar, вам нужно только наследовать класс ormar.Model.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Определение поля
Затем одно или несколько полей назначаются как переменные уровня класса.
Базовый тип поля
Каждая таблица должна иметь ключевой столбец, который можно задать, установив Primary_key =True в выбранном поле.
Допускается только один первичный столбец.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!Предупреждение о том, что отсутствие назначения столбца Primary_key или нескольких столбцов для каждой модели приводит к появлению исключения ModelDefinitionError.
По умолчанию параметр автоприращения имеет значение true, если первичный ключ назначается цельному полю.
Можно отключить, передав autoincrement=False.
| id: int = ormar.Integer(primary_key =True, autoincrement=False)
|
Поля, не относящиеся к базе данных
Обратите внимание, что если в вашей модели требуется обычное поле pydantic (которое используется для хранения значений или передачи определенных значений на модели), вы можете определить поле в pydantic как обычно.
Поля, созданные таким образом, добавляются в поля модели pydantic->, таким образом проверяются на основе типа поля и отображаются в результатах model_dump () и model_dump_json ().
Разница заключается в том, что поля не сохраняются в базе данных. Поэтому они не включаются в нижние столбцы sqlchemy или табличные переменные (см. ниже внутренний раздел, чтобы узнать, как получить доступ к содержимому, когда это необходимо).
В дальнейшем поле pydantic не будет включено в миграцию или любые операции с базой данных (например, сохранение, обновление и т. д.).
Поля, подобные этому, могут быть переданы в полезную нагрузку запроса fastapi и возвращены в ответ fastapi (конечно, только если вы устанавливаете их значения в каком-либо месте в коде, поскольку они не были получены из базы данных. Если вы передаете значение в fastapirequest и возвращаете тот же экземпляр, который fastapi создал для вас в request_model, вы должны вернуть точно то же значение в ответ).
!!! Поля warning pydantic всегда должны быть необязательными и не могут быть изменены (в противном случае проверка загрузки базы данных будет неудачной)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | import databases
import ormar
import pydantic
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
non_db_field: str = pydantic.Field(max_length=100)
|
Если вы задаете поле pydantic с параметрами по умолчанию и не передаете действительное значение в запросе, вы всегда получите значение по умолчанию. Так как это может быть функция, вы можете установить default= datetime.datetime.now и получать текущую метку времени при каждом вызове конечной точки и т. д.
Поля, не относящиеся к базе данных, в Fastapi
Обратите внимание, что поля модификации pydantic и calculated_fields могут включать/исключать из ответов model_dump () и fastapi, соответственно, и response_model_include/response_model_model_exclude.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 | <==part of related code removed for clarity==>
«Органа»((
Database=databases.Database(DATABASE),
metadata= sqalchemy (),
engine= sqlalchemy.create_engine (DATABASE),
)
Класс пользователя (ormar.Model):
ormar_config = base_ormar_config.copy (tablename="users2")
id: int = ormar.Integer(primary_key =True)
email: str = ormar.String(max_length =255, nullable=False)
password: str = ormar.String(max_length =255)
first_name: str = ormar.String(max_length =255)
last_name: str = ormar.String(max_length =255)
категория: str = ormar.String(max_length =255, nullable=True)
Смартфон ((
default= datetime.datetime.now
)
<==part of related code removed for clarity==>
app = FastAPI()
app.post ("/users/")
async def create_user (user: User):
Return user.save ()
<==part of related code removed for clarity==>
def test_excluding_fields_in_endpoints ()
Client = TestClient(приложение)
С клиентом:
Temestamp = datetime.datetime.now ()
user = {
"email": "test@domain.com",
"password": "^*^%A*DA*IAAA",
"first_name": "John",
"last_name": "Doe",
"timestamp": str(timestamp),
}
response = client.post ("/users/", json=user)
assert list(response.json ().keys()) = [
"id",
"email",
«first_name»,
"last name",
"Категория",
«Timestamp»,
]
Returned Is the Same timestamp
assert respons.json ().get("timestamp") == str(timestamp).replace(" ", "T")
===part of related code removed for clarity===>
|
Имена полей и столбцов
По умолчанию имена полей используются для базовой модели pydantic и таблицы sqalchemy.
Если по какой-либо причине требуется изменить имя в базе данных, но сохранить его в модели, это можно сделать, указав параметр имени во время объявления поля
Вот пример модели, имя которой изменилось.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import databases
import ormar
import sqlalchemy
DATABASE_URl = "sqlite:///test.db"
database = databases.Database(DATABASE_URl, force_rollback=True)
metadata = sqlalchemy.MetaData()
class Child(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="children",
)
id: int = ormar.Integer(name="child_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
born_year: int = ormar.Integer(name="year_born", nullable=True)
|
Обратите внимание, что вы также можете изменить название столбца внешнего ключа
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | from typing import Optional
import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///test.db", force_rollback=True)
metadata = sqlalchemy.MetaData()
class Artist(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="artists",
)
id: int = ormar.Integer(name="artist_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
born_year: int = ormar.Integer(name="year")
class Album(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="music_albums",
)
id: int = ormar.Integer(name="album_id", primary_key=True)
name: str = ormar.String(name="album_name", max_length=100)
artist: Optional[Artist] = ormar.ForeignKey(Artist, name="artist_id")
|
Но на данный момент изменить имена столбцов ManyToMany невозможно, так как они будут проходить через другие модели.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 | import databases
import ormar
import sqlalchemy
DATABASE_URl = "sqlite:///test.db"
database = databases.Database(DATABASE_URl, force_rollback=True)
metadata = sqlalchemy.MetaData()
class Child(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="children",
)
id: int = ormar.Integer(name="child_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
born_year: int = ormar.Integer(name="year_born", nullable=True)
class ArtistChildren(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="children_x_artists",
)
class Artist(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="artists",
)
id: int = ormar.Integer(name="artist_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
born_year: int = ormar.Integer(name="year")
children = ormar.ManyToMany(Child, through=ArtistChildren)
|
Переопределение набора запросов по умолчанию
Если вы хотите настроить запросы, выполняемые ormar, вы можете определить свой собственный класс набора запросов в классе модели (с расширением ormar QuerySet). По умолчанию используется QuerySet.
Можно предоставить новый класс в качестве параметра queryset_class в файле ormar_config класса.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | import ormar
Queryset Import Queryset QuerySet
from fastapi import HTTP Exception
Class MyQuerySetClass(QuerySet):
async def first_or_404(self, *args, **kwargs):
entity = await self.get_or_none (*args, **kwargs)
Если entity is None:
# in fastapi or starlette
HTTP Exception (404)
Модель (Ormar):
10.00.201.201.201.2011
queryset_class =MyQuerySetClass,
tablename="book",
)
id: int = ormar.Integer(primary_key =True)
name: str = ormar.String(max_length =32)
#Когда книга не found, raise `404` in your view
book = await Book.objects.first_or_404(name="123")
|
Советы по типам
Обратите внимание, что для лучшей поддержки IDE и проверки mypy вы можете предоставить подсказки типов.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Обратите внимание, что подсказки типа необязательны, поэтому полностью действительный код ormar может выглядеть следующим образом:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id = ormar.Integer(primary_key=True)
name = ormar.String(max_length=100)
completed = ormar.Boolean(default=False)
|
!!!Предупреждение, даже если вы используете подсказки типа, Ormar не будет использовать их для создания поля pydantic!
| Type hints are only to support static checkers and linting,
`ormar` construct annotations used by `pydantic` from own fields.
|
Зависимость
Поскольку ormar полагается на базы данных и sqlchemy-core для подключения к базе данных и создания таблиц, вам нужно назначить два специальных параметра для каждой модели.
Базы данных
Один из них-это экземпляр базы данных, созданный с помощью sqlchemy для подключения URL-адреса в формате строки.
Создаваемые экземпляры должны быть переданы каждой модели с использованием параметра базы данных объекта ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!Запрос на создание экземпляра базы данных только один раз и использование его для всех моделей. Если вы хотите использовать несколько баз данных, вы можете создать несколько баз данных.
Алхимия
Вторая зависимость-это экземпляр sqlalchemy MetaData.
Создаваемые экземпляры должны быть переданы каждой модели с помощью параметра метаданных объекта ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!Создайте экземпляр MetaData только один раз и используйте его для всех моделей. Если вы хотите использовать несколько баз данных, вы можете создать несколько баз данных.
Лучшие Лраки
Обратите внимание, что для ormar требуется поле ormar_config, которое является экземпляром класса OrmarConfig. Для упрощения управления конфигурацией класс OrmarConfig предоставляет метод копирования. Поэтому вместо того, чтобы предоставлять одинаковые параметры для всех моделей снова и снова, необходимо создать базовый объект и использовать его копию.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | from typing import Optional
import databases
import ormar
import sqlalchemy
DATABASE_URL = "sqlite:///test.db"
ormar_base_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL),
metadata=sqlalchemy.MetaData(),
)
class Artist(ormar.Model):
# note that tablename is optional
# if not provided ormar will user class.__name__.lower()+'s'
# -> artists in this example
ormar_config = ormar_base_config.copy()
id: int = ormar.Integer(primary_key=True)
first_name: str = ormar.String(max_length=100)
last_name: str = ormar.String(max_length=100)
born_year: int = ormar.Integer(name="year")
class Album(ormar.Model):
ormar_config = ormar_base_config.copy()
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
artist: Optional[Artist] = ormar.ForeignKey(Artist)
|
Название таблицы
По умолчанию имена таблиц создаются на основе имен классов модели, то есть строчные буквы с буквой "s".
Этот параметр можно переопределить, указав параметр имени таблицы для объекта ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
# if you omit this parameter it will be created automatically
# as class.__name__.lower()+'s' -> "courses" in this example
tablename="my_courses",
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Зависимости
На уровне модели можно также установить ограничения для столбцов SQL.
В настоящее время поддерживаются только зависимости IndexColumns, UniqueColumns и CheckColumns.
!!!note Обратите внимание, что эти две зависимости следует использовать только в том случае, если вы хотите задать имя зависимости или индексировать несколько столбцов, в противном случае предпочтение отдается индексу и уникальным свойствам в поле ormar.
!!!tip Для получения дополнительной информации об ограничениях столбцов, таких как первичный ключ, уникальный ключ, внешний ключ и т. д., перейдите в поле.
Уникальная колонна.
Этот параметр можно задать, указав параметр объектной зависимости ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
# define your constraints in OrmarConfig of the model
# it's a list that can contain multiple constraints
# hera a combination of name and column will have to be unique in db
constraints=[ormar.UniqueColumns("name", "completed")],
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!note Обратите внимание, что зависимости связаны с комбинацией столбцов, которые должны быть уникальными. Чтобы сделать столбец уникальным, используйте уникальный общий параметр. Конечно, вы можете использовать этот параметр, чтобы сделать множество столбцов уникальными, но каждый столбец будет проверяться отдельно.
Столбцы индекса
Этот параметр можно задать, указав параметр объектной зависимости ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
# define your constraints in OrmarConfig of the model
# it's a list that can contain multiple constraints
# hera a combination of name and column will have a compound index in the db
constraints=[ormar.IndexColumns("name", "completed")],
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!note Обратите внимание, что ограничения связаны с комбинацией столбцов, которые должны быть включены в индекс. Чтобы задать индекс, используйте уникальный общий параметр. Конечно, вы можете использовать этот параметр для индексирования многих столбцов, но каждый столбец будет иметь отдельный индекс.
Проверить столбцы
Этот параметр можно задать, указав параметр объектной зависимости ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | import datetime
import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
# define your constraints in OrmarConfig of the model
# it's a list that can contain multiple constraints
# hera a combination of name and column will have a level check in the db
constraints=[
ormar.CheckColumns("start_time < end_time", name="date_check"),
],
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
start_date: datetime.date = ormar.Date()
end_date: datetime.date = ormar.Date()
|
!!!Примечание Обратите внимание, что некоторые базы данных не поддерживают ограничения проверки (например, MySQL).
Конструкция консоли
Поскольку каждая модель ormar.Model также является pydantic, вам может потребоваться скорректировать настройки конфигурации pydantic.
В pydantic это делается путем корректировки настроек в словаре модели_config, поставляемой модели, и это работает точно так же, как и модель ormar.
Таким образом, чтобы настроить свои собственные предпочтения, вам нужно предоставить модель не только класс ormar_config, но и класс model_config = ConfigDict().
!!!note Чтобы узнать больше о доступных настройках, посетите страницу конфигурации pydantic.
Обратите внимание, что если вы не предоставите свою собственную конфигурацию, ormar сделает это для вас. Доступные конфигурации по умолчанию следующие:
| model_config = ConfigDict(validate_assignment =True, ser_json_bytes ="base64")
|
Таким образом, переопределите параметры или представите собственные примеры моделей следующим образом:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | import databases
import ormar
import pydantic
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
model_config = pydantic.ConfigDict(frozen=True)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Дополнительные поля в моделях
По умолчанию ormar запрещает передачу дополнительных полей в модель.
Если вы попытаетесь сделать это, будет генерирована ошибка ModelError.
Поскольку дополнительные поля не могут быть сохранены в базе данных, их запрещение по умолчанию представляется целесообразным.
Вместо этого в pydantic параметр по умолчанию-игнорировать такие дополнительные поля, поэтому ormar предоставляет параметры ormar_config.extra, которые работают таким же образом.
Чтобы пропустить дополнительные поля, переданные ormar, установите для этого значение Extra.ignore вместо значения Extra.forbid по умолчанию.
Обратите внимание, что ormar не позволяет принимать дополнительные поля, вы можете только игнорировать их или запретить их (что приводит к исключению, если они существуют)
| Из Ormar Import Extra, OrmarConfig
Class Child(Ormar.Model):
«Органа»((
tablename="Дети",
extra signore # set extra setting to prevent exceptions on extra fields presence
)
id: int = ormar.Integer(name="child_id", primary_key =True)
first_name: str = ormar.String(name="fname", max_length =100)
last_name: str = ormar.String(name="lname", max_length =100)
|
Чтобы установить одинаковые параметры для всех моделей, проверьте рекомендации и концепцию base_ormar_config.
Сортировать модель
По умолчанию при запросе базы данных с использованием данной модели модели модель сортируется по возрастанию по столбцу Primary_key. Если вы хотите изменить поведение по умолчанию, это можно сделать, предоставив параметр orders_by модели или объекту mar_config.
Пример сортировки по умолчанию (не указан-поэтому указан первичным ключом):
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | «Органа»((
Database=databases.Database(DATABASE),
metadata= sqalchemy (),
)
# default sort by column id ascending
Класс автора (ormar.Model):
10.00.201.201.201.2011
tablename="authors",
)
id: int = ormar.Integer(primary_key =True)
name: str = ormar.String(max_length =100)
|
Измененные
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | «Органа»((
Database=databases.Database(DATABASE),
metadata= sqalchemy (),
)
# Now default sort by name descending
Класс автора (ormar.Model):
10.00.201.201.201.2011
orders_by = ["-name"],
tablename="authors",
)
id: int = ormar.Integer(primary_key =True)
name: str = ormar.String(max_length =100)
|
Инициализация модели
Существует два способа создания и сохранения экземпляров модели в базе данных.
Если планируется изменить экземпляр позже при запуске программы, можно запустить модель как обычный класс и дождаться вызова save().
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | import asyncio
import databases
import ormar
import sqlalchemy
from examples import create_drop_database
DATABASE_URL = "sqlite:///test.db"
ormar_base_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL), metadata=sqlalchemy.MetaData()
)
class Course(ormar.Model):
ormar_config = ormar_base_config.copy(tablename="courses")
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
@create_drop_database(base_config=ormar_base_config)
async def run_query():
course = Course(name="Painting for dummies", completed=False)
await course.save()
await Course.objects.create(name="Painting for dummies", completed=False)
asyncio.run(run_query())
|
Для запуска модели и сохранения ее в базе данных используйте метод QuerySet create().
Для создания нескольких объектов одновременно можно использовать метод bulk_create () QuerySet.
Каждая модель имеет набор запросов, инициализированных как параметр объекта
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | import asyncio
import databases
import ormar
import sqlalchemy
from examples import create_drop_database
DATABASE_URL = "sqlite:///test.db"
ormar_base_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL), metadata=sqlalchemy.MetaData()
)
class Course(ormar.Model):
ormar_config = ormar_base_config.copy(tablename="courses")
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
@create_drop_database(base_config=ormar_base_config)
async def run_query():
course = Course(name="Painting for dummies", completed=False)
await course.save()
await Course.objects.create(name="Painting for dummies", completed=False)
asyncio.run(run_query())
|
!!!info Для получения дополнительной информации о наборах запросов (включая пакетные операции) и доступных методах, посетите Запрос
Состояние сохранения модели
Каждый экземпляр модели представляет собой отдельный объект Python, который ничего не знает друг о друге.
| track1 = await Track.objects.get (name ='The Bird')
track2 = await Track.objects.get (name ='The Bird')
track1 == track2 # True
track1.name = 'The Bird2'
track1.save (
assert track1.name == track2.name # False
## track2 does not update and knows nothing about track1
|
Сам объект имеет состояние сохранения, которое можно задать следующим образом.
- Сохранить модель после сохранения/обновления/загрузки/обновления метода вставки в модели
- модель после сохранения метода
create/get/first/all/get_or_create/update_or_create
- Модель сохраняется при передаче в bulk_update и bulk_create.
- Сохранение модели после добавления/удаления связанных объектов ManyToMany (автоматическое сохранение/удаление из экземпляра модели)
- Модель не сохраняется при изменении каких-либо собственных полей (включая pk в качестве псевдонима Model.pk)
- После добавления/удаления связанных объектов ForeignKey модель не сохраняется (столбец fk не сохранен)
- использует__init__Экземпляр модели без сохранения (без использования QuerySet.create или до вызова save)
Можно проверить сохранение модели с помощью свойства ModelInstance.saved