Skip to content

Insert data into database

Following methods allow you to insert data into the 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_related() method
  • QuerysetProxy

    • 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

Creates the model instance, saves it in a database and returns the updates model (with pk populated if not passed and autoincrement is set).

The allowed kwargs are Model fields names and proper value types.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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)
1
2
malibu = await Album.objects.create(name="Malibu")
await Track.objects.create(album=malibu, title="The Bird", position=1)

The alternative is a split creation and persistence of the Model.

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

Tip

Check other Model methods in models

get_or_create

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

Combination of create and get methods.

Tries to get a row meeting the criteria and if NoMatch exception is raised it creates a new one with given kwargs and _defaults.

When _defaults dictionary is provided the values set in _defaults will always be set, including overwriting explicitly provided values. i.e. get_or_create(_defaults: {"title": "I win"}, title="never used") will always use "I win" as title whether you provide your own value in kwargs or not.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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()
1
2
3
4
5
6
7
8
9
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

Warning

Despite being a equivalent row from database the album and album2 in example above are 2 different python objects! Updating one of them will not refresh the second one until you explicitly load() the fresh data from db.

Note

Note that if you want to create a new object you either have to pass pk column value or pk column has to be set as autoincrement

update_or_create

update_or_create(**kwargs) -> Model

Updates the model, or in case there is no match in database creates a new one.

 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

Note that if you want to create a new object you either have to pass pk column value or pk column has to be set as 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 methods

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

save

You can create new models by using QuerySet.create() method or by initializing your model as a normal pydantic model and later calling save() method.

Tip

Read more about save() method in models-save

upsert

It's a proxy to either save() or update(**kwargs) methods of a Model. If the pk is not set the save() method will be called.

Tip

Read more about upsert() method in models-upsert

Method goes through all relations of the Model on which the method is called, and calls upsert() method on each model that is not saved.

Tip

Read more about save_related() method in models-save-related

QuerysetProxy methods

When access directly the related ManyToMany field as well as ReverseForeignKey returns the list of related models.

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

create

Works exactly the same as create function above but allows you to create related objects from other side of the relation.

Tip

To read more about QuerysetProxy visit querysetproxy section

get_or_create

Works exactly the same as get_or_create function above but allows you to query or create related objects from other side of the relation.

Tip

To read more about QuerysetProxy visit querysetproxy section

update_or_create

Works exactly the same as update_or_create function above but allows you to update or create related objects from other side of the relation.

Tip

To read more about QuerysetProxy visit querysetproxy section