File: docs008.py

package info (click to toggle)
ormar 0.21.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,856 kB
  • sloc: python: 23,666; makefile: 34; sh: 14
file content (114 lines) | stat: -rw-r--r-- 3,522 bytes parent folder | download
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import asyncio

import databases
import ormar
import sqlalchemy
from examples import create_drop_database
from pydantic import ValidationError

DATABASE_URL = "sqlite:///test.db"

ormar_base_config = ormar.OrmarConfig(
    database=databases.Database(DATABASE_URL),
    metadata=sqlalchemy.MetaData(),
)


class Company(ormar.Model):
    ormar_config = ormar_base_config.copy(tablename="companies")

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


class Car(ormar.Model):
    ormar_config = ormar_base_config.copy(tablename="cars")

    id: int = ormar.Integer(primary_key=True)
    manufacturer = ormar.ForeignKey(Company)
    name: str = ormar.String(max_length=100)
    year: int = ormar.Integer(nullable=True)
    gearbox_type: str = ormar.String(max_length=20, nullable=True)
    gears: int = ormar.Integer(nullable=True)
    aircon_type: str = ormar.String(max_length=20, nullable=True)


@create_drop_database(base_config=ormar_base_config)
async def run_query():
    # build some sample data
    toyota = await Company.objects.create(name="Toyota", founded=1937)
    await Car.objects.create(
        manufacturer=toyota,
        name="Corolla",
        year=2020,
        gearbox_type="Manual",
        gears=5,
        aircon_type="Manual",
    )
    await Car.objects.create(
        manufacturer=toyota,
        name="Yaris",
        year=2019,
        gearbox_type="Manual",
        gears=5,
        aircon_type="Manual",
    )
    await Car.objects.create(
        manufacturer=toyota,
        name="Supreme",
        year=2020,
        gearbox_type="Auto",
        gears=6,
        aircon_type="Auto",
    )

    # select manufacturer but only name,
    # to include related models use notation {model_name}__{column}
    all_cars = (
        await Car.objects.select_related("manufacturer")
        .exclude_fields(
            ["year", "gearbox_type", "gears", "aircon_type", "manufacturer__founded"]
        )
        .all()
    )
    for car in all_cars:
        # excluded columns will yield None
        assert all(
            getattr(car, x) is None
            for x in ["year", "gearbox_type", "gears", "aircon_type"]
        )
        # included column on related models will be available,
        # pk column is always included
        # even if you do not include it in fields list
        assert car.manufacturer.name == "Toyota"
        # also in the nested related models -
        # you cannot exclude pk - it's always auto added
        assert car.manufacturer.founded is None

    # fields() can be called several times,
    # building up the columns to select,
    # models selected in select_related
    # but with no columns in fields list implies all fields
    all_cars = (
        await Car.objects.select_related("manufacturer")
        .exclude_fields("year")
        .exclude_fields(["gear", "gearbox_type"])
        .all()
    )
    # all fiels from company model are selected
    assert all_cars[0].manufacturer.name == "Toyota"
    assert all_cars[0].manufacturer.founded == 1937

    # cannot exclude mandatory model columns -
    # manufacturer__name in this example - note usage of dict/set this time
    try:
        await Car.objects.select_related("manufacturer").exclude_fields(
            {"manufacturer": {"name"}}
        ).all()
    except ValidationError:
        # will raise pydantic ValidationError as company.name is required
        pass


asyncio.run(run_query())