Перейти к содержанию

Обновить данные в базе данных

Следующие методы и функции позволяют обновлять существующие данные в базе данных.

  • update(each: bool = False, **kwargs) -> int

  • update_or_create(**kwargs) -> Model

  • bulk_update(objects: List[Model], columns: List[str] = None) -> None

  • Модель

    • Метод update ()
    • Метод Model. upsert ()
    • Model.save
    • Агент набора запросов

    • QuerysetProxy.update_or_create(**kwargs) Методология

Обновить

update(each: bool = False, **kwargs) -> int

Обновление уровня QuerySet используется для одновременного обновления нескольких записей с одним и тем же значением.

Для обновления всей таблицы необходимо либо отфильтровать QuerySet, либо ввести флаг each = True.

Если вы не предоставляете этот флаг или фильтр, будет генерироваться QueryDefinitionError.

Возвращает обновленное число строк.

 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
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 Book(ormar.Model):
    ormar_config = ormar_base_config.copy(
        tablename="books",
    )

    id: int = ormar.Integer(primary_key=True)
    title: str = ormar.String(max_length=200)
    author: str = ormar.String(max_length=100)
    genre: str = ormar.String(
        max_length=100,
        default="Fiction",
    )


@create_drop_database(base_config=ormar_base_config)
async def run_query():
    await Book.objects.create(
        title="Tom Sawyer", author="Twain, Mark", genre="Adventure"
    )
    await Book.objects.create(
        title="War and Peace", author="Tolstoy, Leo", genre="Fiction"
    )
    await Book.objects.create(
        title="Anna Karenina", author="Tolstoy, Leo", genre="Fiction"
    )

    await Book.objects.update(each=True, genre="Fiction")
    all_books = await Book.objects.filter(genre="Fiction").all()
    assert len(all_books) == 3


asyncio.run(run_query())

!!!Предупреждение о необходимости фильтрации набора запросов перед обновлением во избежание случайного переопределения.

1
To update whole table `each=True` needs to be provided as a safety switch

Обновить или создать

update_or_create(**kwargs) -> Model

Обновление модели или создание новой модели без соответствия в базе данных.

 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
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 Book(ormar.Model):
    ormar_config = ormar_base_config.copy()

    id: int = ormar.Integer(primary_key=True)
    title: str = ormar.String(max_length=200)
    author: str = ormar.String(max_length=100)
    genre: str = ormar.String(
        max_length=100,
        default="Fiction",
    )


@create_drop_database(base_config=ormar_base_config)
async def run_query():
    await Book.objects.create(
        title="Tom Sawyer", author="Twain, Mark", genre="Adventure"
    )
    await Book.objects.create(
        title="War and Peace", author="Tolstoy, Leo", genre="Fiction"
    )
    await Book.objects.create(
        title="Anna Karenina", author="Tolstoy, Leo", genre="Fiction"
    )

    # if not exist the instance will be persisted in db
    vol2 = await Book.objects.update_or_create(
        title="Volume II", author="Anonymous", genre="Fiction"
    )
    assert await Book.objects.count() == 4

    # if pk or pkname passed in kwargs (like id here) the object will be updated
    assert await Book.objects.update_or_create(id=vol2.id, genre="Historic")
    assert await Book.objects.count() == 4


asyncio.run(run_query())

Обратите внимание, что если вы хотите создать новый объект, вы должны либо передать значение столбца pk, либо установить автоматическое приращение столбца pk.

Пакетные обновления

bulk_update(objects: List["Model"], columns: List[str] = None) -> None

Позволяет одновременно обновлять несколько экземпляров.

Все передаваемые модели должны быть заполнены ключевыми столбцами.

Можно также выбрать поля для обновления, передав список столбцов в виде списка имен строк.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#Continuing the example from bulk_create
#update objects
Для Todo in todoes:
    todo.completed = False

# perform update of all objects at once
#objts need to have pk column set, otherwise exception is raised
await ToDo.objects.bulk_update (todoes)

completed = await ToDo.objects.filter(completed=False).all()
assert len(completed) = 3

Метод модели

Каждый экземпляр модели имеет набор способов сохранения, обновления или загрузки самого себя.

обновление

Вы можете обновить модель, обновив свойства модели (поля) и вызовав метод update().

При попытке обновить модель без установки первичного ключа будет генерировано исключение ModelPersistenceError.

!!!tip Узнайте больше о методе update() в models-update

Обновить вставку

Он является агентом метода save() или update(**kwargs) модели. Если установлен pk, вызывается метод update().

!!!tip Подробнее о методе upsert() в models-upsert

Сохранить связь

Метод проходит через все связи модели, к которой он был применен, и вызывает метод upsert() для каждой из несохраненных моделей.

!!!tip Подробнее о методе save_lated () в models-save-lated

Метод QuerysetProxy

При прямом доступе к соответствующему полю ManyToMany и ReverseForeignKey, возвращайтесь к списку связанных моделей.

Но в то же время он предоставляет подмножество API QuerySet, поэтому вы можете фильтровать, создавать и выбирать связанные модели непосредственно из родительской модели.

Обновить или создать

То же самое, что и функция update_or_create выше, но позволяет обновлять или создавать связанные объекты с другого конца отношения.

Tip