File: multi-model.md

package info (click to toggle)
python-beanie 2.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,480 kB
  • sloc: python: 14,427; makefile: 7; sh: 6
file content (82 lines) | stat: -rw-r--r-- 1,746 bytes parent folder | download | duplicates (2)
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
# Multi-model pattern

Documents with different schemas could be stored in a single collection and managed correctly. 
`UnionDoc` class is used for this.

It supports `find` and `aggregate` methods. 
For `find`, it will fetch all the found documents into the respective `Document` classes.

Documents with `union_doc` in their settings can still be used in `find` and other queries. 
Queries of one such class will not see the data of others.

## Example

Create documents:

```python
from beanie import Document, UnionDoc


class Parent(UnionDoc):  # Union
    class Settings:
        name = "union_doc_collection"  # Collection name
        class_id = "_class_id"  # _class_id is the default beanie internal field used to filter children Documents
        
        
class One(Document):
    int_field: int = 0
    shared: int = 0        

    class Settings:
        name = "One" # Name used to filer union document 'One', default to class name
        union_doc = Parent


class Two(Document):
    str_field: str = "test"
    shared: int = 0

    class Settings:
        union_doc = Parent
```

The schemas could be incompatible.

Insert a document

```python
await One().insert()
await One().insert()
await One().insert()

await Two().insert()
```

Find all the documents of the first type:

```python
docs = await One.all().to_list()
print(len(docs))

>> 3 # It found only documents of class One
```

Of the second type:

```python
docs = await Two.all().to_list()
print(len(docs))

>> 1 # It found only documents of class Two
```

Of both:

```python
docs = await Parent.all().to_list()
print(len(docs))

>> 4 # instances of both classes will be in the output here
```

Aggregations will work separately for these two document classes too.