Skip to content

Inserting data into a database

The following methods allow you to insert data into a database.

  • create (**kwargs) -> model

  • get_or_create(_defaults: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Model, bool]

  • update_or_create(**kwargs) -> Model

  • bulk_create(objects: List[Model]) -> None

  • Model*Model.save () Method*Model.upsert() Method* Model.save_lated() Method

  • query set proxy* QuerysetProxy.create(**kwargs) method* QuerysetProxy.get_or_create(_defaults: Optional[Dict[str, Any]] = None, **kwargs) method*QuerysetProxy.update_or_create(**kwargs) method

create

Create (**kwargs): -> Model

Create a model instance, save it in the database and return the updated model (fill in pk if not passed and autoincrement is set).

Allowed kwargs are model field names and correct value types.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Album(ormar.Model):
    ormar_config = ormar.OrmarConfig(
        database=database,
        metadata=metadata,
        tablename="album"
    )


    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)


malibu = await Album.objects.create(name="Malibu")
await Track.objects.create(album=malibu, title="The Bird", position=1)

Another approach is split creation and persistence of models.

1
2
malibu = Album(name="Malibu")
await malibu.save()

Tip

acquiring or creating

get_or_create(_defaults: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Model, bool]

A combination of create and get methods.

Attempts to get rows that meet the condition, and if a NoMatch exception is thrown, a new row is created with the given kwargs and_defaults.

When a_defaults dictionary is provided, the values set in_defaults are always set, including overriding explicitly provided values. IE get_or_create(_defaults: {"title": "I win"}, title="never used") will always use "I win" as the title regardless of whether you provide your own value in kwargs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Album(ormar.Model):
    ormar_config = ormar.OrmarConfig(
        database=database,
        metadata=metadata,
        tablename="album"
    )

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
    year: int = ormar.Integer()


album, created = await Album.objects.get_or_create(name='The Cat', _defaults={"year": 1999})
assert created is True
assert album.name == "The Cat"
assert album.year == 1999
# object is created as it does not exist
album2, created = await Album.objects.get_or_create(name='The Cat')
assert created is False
assert album == album2
# return True as the same db row is returned

!!!warns that despite being equivalent rows in the database, album and album2 in the example above are 2 different python objects! Updating one of them does not refresh the second until you explicitly load () new data from the database.

Note that if you want to create a new object, you must either pass the pk column value or the pk column must be set to autoincrement

update or create

update_or_create(**kwargs) -> Model

Update the model or create a new model if there are no matches in the database.

 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())

Note that if you want to create a new object, you must either pass the pk column value or the pk column must be set to autoincrement

bulk create

bulk_create(objects: List["Model"]) -> None

Allows you to create multiple objects at once.

A valid list of model objects needs to be passed.

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

    id: int = ormar.Integer(primary_key=True)
    text: str = ormar.String(max_length=500)
    completed = ormar.Boolean(default=False)


@create_drop_database(base_config=ormar_base_config)
async def run_query():
    # create multiple instances at once with bulk_create
    await ToDo.objects.bulk_create(
        [
            ToDo(text="Buy the groceries."),
            ToDo(text="Call Mum.", completed=True),
            ToDo(text="Send invoices.", completed=True),
        ]
    )

    todoes = await ToDo.objects.all()
    assert len(todoes) == 3


asyncio.run(run_query())

model method

Each model instance has a set of methods to save, update, or load itself.

Save

You can create a new model using the QuerySet.create() method or initializing the model to a normal pydantic model and then calling the save() method.

!!!tip Read more about the save() method in models-save

Update insert

It is a proxy for the model's save() or update(**kwargs) methods. If pk is not set, the save() method is called.

!!!tip Read more about the upsert() method in models-upsert

Method iterates through all relationships of the model calling it and calls the upsert() method on each unsaved model.

!!!tip Read more about the save_lated() method in models-save-lated

QuerysetProxy method

Returns a list of related models when directly accessing the related ManyToMany field and ReverseForeignKey.

But at the same time it exposes a subset of the QuerySet API, so you can filter, create, select related models, etc. directly from the parent model.

create

Identical to the create function above, but allows you to create related objects from the other end of the relationship.

!!!tip To learn more about QuerysetProxy, visit the QuerysetProxy section

acquiring or creating

Identical to the get_or_create function above, but allows you to query or create related objects from the other end of the relationship.

!!!tip To learn more about QuerysetProxy, visit the QuerysetProxy section

update or create

Identical to the update_or_create function above, but allows you to update or create related objects from the other end of the relationship.

!!!tip To learn more about QuerysetProxy, visit the QuerysetProxy section