File: test_prefetch_related_with_same_models.py

package info (click to toggle)
ormar 0.22.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,952 kB
  • sloc: python: 24,085; makefile: 34; sh: 14
file content (119 lines) | stat: -rw-r--r-- 3,965 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
115
116
117
118
119
from random import randint
from typing import ForwardRef, Optional

import ormar
import pytest
from faker import Faker
from ormar.relations.relation_proxy import RelationProxy

from tests.lifespan import init_tests
from tests.settings import create_config

base_ormar_config = create_config()
fake = Faker()


class Author(ormar.Model):
    ormar_config = base_ormar_config.copy(tablename="authors")

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


class BookAuthor(ormar.Model):
    ormar_config = base_ormar_config.copy(tablename="book_authors")

    id: int = ormar.Integer(primary_key=True)


class BookCoAuthor(ormar.Model):
    ormar_config = base_ormar_config.copy(tablename="book_co_authors")

    id: int = ormar.Integer(primary_key=True)


class Book(ormar.Model):
    ormar_config = base_ormar_config.copy(tablename="books")

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=256)
    description: Optional[str] = ormar.String(max_length=256, nullable=True)
    authors: RelationProxy[Author] = ormar.ManyToMany(
        Author, related_name="author_books", through=BookAuthor
    )
    co_authors: RelationProxy[Author] = ormar.ManyToMany(
        Author, related_name="co_author_books", through=BookCoAuthor
    )


class SelfRef(ormar.Model):
    ormar_config = base_ormar_config.copy(tablename="selfrefs")

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
    main_child = ormar.ForeignKey(to=ForwardRef("SelfRef"), related_name="parent")
    children: RelationProxy["SelfRef"] = ormar.ManyToMany(ForwardRef("SelfRef"))


SelfRef.update_forward_refs()

create_test_database = init_tests(base_ormar_config)


@pytest.mark.asyncio
async def test_prefetch_related_with_same_model_relations() -> None:
    async with base_ormar_config.database:
        for _ in range(6):
            await Author.objects.create(name=fake.name())

        book = await Book.objects.create(name=fake.sentence(nb_words=randint(1, 4)))
        for i in range(1, 3):
            await book.authors.add(await Author.objects.get(id=i))
        for i in range(3, 6):
            await book.co_authors.add(await Author.objects.get(id=i))

        prefetch_result = await Book.objects.prefetch_related(
            ["authors", "co_authors"]
        ).all()
        prefetch_dict_result = [x.model_dump() for x in prefetch_result if x.id == 1][0]
        select_result = await Book.objects.select_related(
            ["authors", "co_authors"]
        ).all()
        select_dict_result = [
            x.model_dump(
                exclude={
                    "authors": {"bookauthor": ...},
                    "co_authors": {"bookcoauthor": ...},
                }
            )
            for x in select_result
            if x.id == 1
        ][0]
        assert prefetch_dict_result == select_dict_result


@pytest.mark.asyncio
async def test_prefetch_related_with_self_referencing() -> None:
    async with base_ormar_config.database:
        main_child = await SelfRef.objects.create(name="MainChild")
        main = await SelfRef.objects.create(name="Main", main_child=main_child)

        child1 = await SelfRef.objects.create(name="Child1")
        child2 = await SelfRef.objects.create(name="Child2")

        await main.children.add(child1)
        await main.children.add(child2)

        select_result = await SelfRef.objects.select_related(
            ["main_child", "children"]
        ).get(name="Main")
        print(select_result.model_dump_json(indent=4))

        prefetch_result = await SelfRef.objects.prefetch_related(
            ["main_child", "children"]
        ).get(name="Main")

        assert prefetch_result.main_child.name == main_child.name
        assert len(prefetch_result.children) == 2
        assert prefetch_result.children[0].name == child1.name
        assert prefetch_result.children[1].name == child2.name