work on docs in queries
This commit is contained in:
@ -65,7 +65,7 @@ await track.update(name='The Bird Strikes Again')
|
|||||||
|
|
||||||
`upsert(**kwargs) -> self`
|
`upsert(**kwargs) -> self`
|
||||||
|
|
||||||
It's an proxy to either `save()` or `update(**kwargs)` methods described above.
|
It's a proxy to either `save()` or `update(**kwargs)` methods described above.
|
||||||
|
|
||||||
If the primary key is set -> the `update` method will be called.
|
If the primary key is set -> the `update` method will be called.
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,23 @@
|
|||||||
# Create / Insert data into database
|
# Insert data into database
|
||||||
|
|
||||||
* `create(**kwargs): -> Model`
|
Following methods allow you to insert data into the database.
|
||||||
|
|
||||||
|
* `create(**kwargs) -> Model`
|
||||||
* `get_or_create(**kwargs) -> Model`
|
* `get_or_create(**kwargs) -> Model`
|
||||||
* `update_or_create(**kwargs) -> Model`
|
* `update_or_create(**kwargs) -> Model`
|
||||||
* `bulk_create(objects: List[Model]) -> None`
|
* `bulk_create(objects: List[Model]) -> None`
|
||||||
* `Model.save()` method
|
|
||||||
* `Model.upsert()` method
|
|
||||||
|
* `Model`
|
||||||
|
* `Model.save()` method
|
||||||
|
* `Model.upsert()` method
|
||||||
|
* `Model.save_related()` method
|
||||||
|
|
||||||
|
|
||||||
|
* `QuerysetProxy`
|
||||||
|
* `QuerysetProxy.create(**kwargs)` method
|
||||||
|
* `QuerysetProxy.get_or_create(**kwargs)` method
|
||||||
|
* `QuerysetProxy.update_or_create(**kwargs)` method
|
||||||
|
|
||||||
## create
|
## create
|
||||||
|
|
||||||
@ -16,6 +28,17 @@ Creates the model instance, saves it in a database and returns the updates model
|
|||||||
|
|
||||||
The allowed kwargs are `Model` fields names and proper value types.
|
The allowed kwargs are `Model` fields names and proper value types.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Album(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "album"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
malibu = await Album.objects.create(name="Malibu")
|
malibu = await Album.objects.create(name="Malibu")
|
||||||
await Track.objects.create(album=malibu, title="The Bird", position=1)
|
await Track.objects.create(album=malibu, title="The Bird", position=1)
|
||||||
@ -28,7 +51,8 @@ malibu = Album(name="Malibu")
|
|||||||
await malibu.save()
|
await malibu.save()
|
||||||
```
|
```
|
||||||
|
|
||||||
!!!tip Check other `Model` methods in [models][models]
|
!!!tip
|
||||||
|
Check other `Model` methods in [models][models]
|
||||||
|
|
||||||
## get_or_create
|
## get_or_create
|
||||||
|
|
||||||
@ -39,6 +63,17 @@ Combination of create and get methods.
|
|||||||
Tries to get a row meeting the criteria and if `NoMatch` exception is raised it creates
|
Tries to get a row meeting the criteria and if `NoMatch` exception is raised it creates
|
||||||
a new one with given kwargs.
|
a new one with given kwargs.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Album(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "album"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
album = await Album.objects.get_or_create(name='The Cat')
|
album = await Album.objects.get_or_create(name='The Cat')
|
||||||
# object is created as it does not exist
|
# object is created as it does not exist
|
||||||
@ -47,13 +82,15 @@ assert album == album2
|
|||||||
# return True as the same db row is returned
|
# return True as the same db row is returned
|
||||||
```
|
```
|
||||||
|
|
||||||
!!!warning Despite being a equivalent row from database the `album` and `album2` in
|
!!!warning
|
||||||
example above are 2 different python objects!
|
Despite being a equivalent row from database the `album` and `album2` in
|
||||||
Updating one of them will not refresh the second one until you excplicitly load() the
|
example above are 2 different python objects!
|
||||||
fresh data from db.
|
Updating one of them will not refresh the second one until you excplicitly load() the
|
||||||
|
fresh data from db.
|
||||||
|
|
||||||
!!!note Note that if you want to create a new object you either have to pass pk column
|
!!!note
|
||||||
value or pk column has to be set as autoincrement
|
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
|
||||||
|
|
||||||
@ -65,8 +102,9 @@ Updates the model, or in case there is no match in database creates a new one.
|
|||||||
--8<-- "../docs_src/queries/docs003.py"
|
--8<-- "../docs_src/queries/docs003.py"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!!note Note that if you want to create a new object you either have to pass pk column
|
!!!note
|
||||||
value or pk column has to be set as autoincrement
|
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
|
||||||
|
|
||||||
@ -80,4 +118,68 @@ A valid list of `Model` objects needs to be passed.
|
|||||||
--8<-- "../docs_src/queries/docs004.py"
|
--8<-- "../docs_src/queries/docs004.py"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Model method
|
## 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][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][models-upsert]
|
||||||
|
|
||||||
|
###save_related
|
||||||
|
|
||||||
|
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][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](./#create) function above but allows you to create related objects
|
||||||
|
from other side of the relation.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
To read more about `QuerysetProxy` visit [querysetproxy][querysetproxy] section
|
||||||
|
|
||||||
|
|
||||||
|
### get_or_create
|
||||||
|
|
||||||
|
Works exactly the same as [get_or_create](./#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][querysetproxy] section
|
||||||
|
|
||||||
|
|
||||||
|
### update_or_create
|
||||||
|
|
||||||
|
Works exactly the same as [update_or_create](./#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][querysetproxy] section
|
||||||
|
|
||||||
|
[models]: ../models/methods.md
|
||||||
|
[models-save]: ../models/methods.md#save
|
||||||
|
[models-upsert]: ../models/methods.md#upsert
|
||||||
|
[models-save-related]: ../models/methods.md#save_related
|
||||||
|
[querysetproxy]: ../relations/queryset-proxy.md
|
||||||
@ -1,7 +1,17 @@
|
|||||||
# Delete/ remove data from database
|
# Delete data from database
|
||||||
|
|
||||||
|
Following methods allow you to delete data from the database.
|
||||||
|
|
||||||
* `delete(each: bool = False, **kwargs) -> int`
|
* `delete(each: bool = False, **kwargs) -> int`
|
||||||
* `Model.delete()` method
|
|
||||||
|
|
||||||
|
* `Model`
|
||||||
|
* `Model.delete()` method
|
||||||
|
|
||||||
|
|
||||||
|
* `QuerysetProxy`
|
||||||
|
* `QuerysetProxy.remove()` method
|
||||||
|
* `QuerysetProxy.clear()` method
|
||||||
|
|
||||||
## delete
|
## delete
|
||||||
|
|
||||||
@ -20,4 +30,122 @@ Return number of rows deleted.
|
|||||||
--8<-- "../docs_src/queries/docs005.py"
|
--8<-- "../docs_src/queries/docs005.py"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Model method
|
## Model methods
|
||||||
|
|
||||||
|
Each model instance have a set of methods to `save`, `update` or `load` itself.
|
||||||
|
|
||||||
|
### delete
|
||||||
|
|
||||||
|
You can delete model instance by calling `delete()` method on it.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
Read more about `delete()` method in [models methods](../models/methods.md#delete)
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
### remove
|
||||||
|
|
||||||
|
Removal of the related model one by one.
|
||||||
|
|
||||||
|
Removes the relation in the database.
|
||||||
|
|
||||||
|
If you specify the keep_reversed flag to `False` `ormar` will also delete the related model from the database.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Album(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "albums"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
is_best_seller: bool = ormar.Boolean(default=False)
|
||||||
|
|
||||||
|
class Track(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "tracks"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
album: Optional[Album] = ormar.ForeignKey(Album)
|
||||||
|
title: str = ormar.String(max_length=100)
|
||||||
|
position: int = ormar.Integer()
|
||||||
|
play_count: int = ormar.Integer(nullable=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
album = await Album(name="Malibu").save()
|
||||||
|
track1 = await Track(
|
||||||
|
album=album, title="The Bird", position=1, play_count=30,
|
||||||
|
).save()
|
||||||
|
# remove through proxy from reverse side of relation
|
||||||
|
await album.tracks.remove(track1, keep_reversed=False)
|
||||||
|
|
||||||
|
# the track was also deleted
|
||||||
|
tracks = await Track.objects.all()
|
||||||
|
assert len(tracks) == 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### clear
|
||||||
|
|
||||||
|
Removal of all related models in one call.
|
||||||
|
|
||||||
|
Removes also the relation in the database.
|
||||||
|
|
||||||
|
If you specify the keep_reversed flag to `False` `ormar` will also delete the related model from the database.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Album(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "albums"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
is_best_seller: bool = ormar.Boolean(default=False)
|
||||||
|
|
||||||
|
class Track(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "tracks"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
album: Optional[Album] = ormar.ForeignKey(Album)
|
||||||
|
title: str = ormar.String(max_length=100)
|
||||||
|
position: int = ormar.Integer()
|
||||||
|
play_count: int = ormar.Integer(nullable=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
album = await Album(name="Malibu").save()
|
||||||
|
track1 = await Track(
|
||||||
|
album=album,
|
||||||
|
title="The Bird",
|
||||||
|
position=1,
|
||||||
|
play_count=30,
|
||||||
|
).save()
|
||||||
|
track2 = await Track(
|
||||||
|
album=album,
|
||||||
|
title="Heart don't stand a chance",
|
||||||
|
position=2,
|
||||||
|
play_count=20,
|
||||||
|
).save()
|
||||||
|
|
||||||
|
# removes the relation only -> clears foreign keys on tracks
|
||||||
|
await album.tracks.clear()
|
||||||
|
|
||||||
|
# removes also the tracks
|
||||||
|
await album.tracks.clear(keep_reversed=False)
|
||||||
|
```
|
||||||
|
|
||||||
|
[querysetproxy]: ../relations/queryset-proxy.md
|
||||||
@ -1,8 +1,26 @@
|
|||||||
# Filtering and sorting data
|
# Filtering and sorting data
|
||||||
|
|
||||||
|
You can use following methods to filter the data (sql where clause).
|
||||||
|
|
||||||
* `filter(**kwargs) -> QuerySet`
|
* `filter(**kwargs) -> QuerySet`
|
||||||
* `exclude(**kwargs) -> QuerySet`
|
* `exclude(**kwargs) -> QuerySet`
|
||||||
|
* `get(**kwargs) -> Model`
|
||||||
|
* `get_or_create(**kwargs) -> Model`
|
||||||
|
* `all(**kwargs) -> List[Optional[Model]]`
|
||||||
|
|
||||||
|
|
||||||
|
* `QuerysetProxy`
|
||||||
|
* `QuerysetProxy.filter(**kwargs)` method
|
||||||
|
* `QuerysetProxy.exclude(**kwargs)` method
|
||||||
|
* `QuerysetProxy.get(**kwargs)` method
|
||||||
|
* `QuerysetProxy.get_or_create(**kwargs)` method
|
||||||
|
* `QuerysetProxy.all(**kwargs)` method
|
||||||
|
|
||||||
|
And following methods to sort the data (sql order by clause).
|
||||||
|
|
||||||
* `order_by(columns:Union[List, str]) -> QuerySet`
|
* `order_by(columns:Union[List, str]) -> QuerySet`
|
||||||
|
* `QuerysetProxy`
|
||||||
|
* `QuerysetProxy.order_by(columns:Union[List, str])` method
|
||||||
|
|
||||||
## filter
|
## filter
|
||||||
|
|
||||||
@ -36,18 +54,20 @@ You can use special filter suffix to change the filter operands:
|
|||||||
* endswith - like `album__name__endswith='ibu'` (exact end match)
|
* endswith - like `album__name__endswith='ibu'` (exact end match)
|
||||||
* iendswith - like `album__name__iendswith='IBU'` (exact end match case insensitive)
|
* iendswith - like `album__name__iendswith='IBU'` (exact end match case insensitive)
|
||||||
|
|
||||||
!!!note All methods that do not return the rows explicitly returns a QueySet instance so
|
!!!note
|
||||||
you can chain them together
|
All methods that do not return the rows explicitly returns a QueySet instance so
|
||||||
|
you can chain them together
|
||||||
|
|
||||||
So operations like `filter()`, `select_related()`, `limit()` and `offset()` etc. can be chained.
|
So operations like `filter()`, `select_related()`, `limit()` and `offset()` etc. can be chained.
|
||||||
|
|
||||||
Something like `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`
|
Something like `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`
|
||||||
|
|
||||||
!!!warning Note that you do not have to specify the `%` wildcard in contains and other
|
!!!warning
|
||||||
filters, it's added for you. If you include `%` in your search value it will be escaped
|
Note that you do not have to specify the `%` wildcard in contains and other
|
||||||
and treated as literal percentage sign inside the text.
|
filters, it's added for you. If you include `%` in your search value it will be escaped
|
||||||
|
and treated as literal percentage sign inside the text.
|
||||||
|
|
||||||
### exclude
|
## exclude
|
||||||
|
|
||||||
`exclude(**kwargs) -> QuerySet`
|
`exclude(**kwargs) -> QuerySet`
|
||||||
|
|
||||||
@ -67,7 +87,41 @@ notes = await Track.objects.exclude(position_gt=3).all()
|
|||||||
# returns all tracks with position < 3
|
# returns all tracks with position < 3
|
||||||
```
|
```
|
||||||
|
|
||||||
### order_by
|
## 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.
|
||||||
|
|
||||||
|
### get
|
||||||
|
|
||||||
|
Works exactly the same as [get](./#get) function above but allows you to fetch related
|
||||||
|
objects from other side of the relation.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
To read more about `QuerysetProxy` visit [querysetproxy][querysetproxy] section
|
||||||
|
|
||||||
|
### get_or_create
|
||||||
|
|
||||||
|
Works exactly the same as [get_or_create](./#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][querysetproxy] section
|
||||||
|
|
||||||
|
### all
|
||||||
|
|
||||||
|
Works exactly the same as [all](./#all) function above but allows you to query related
|
||||||
|
objects from other side of the relation.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
To read more about `QuerysetProxy` visit [querysetproxy][querysetproxy] section
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## order_by
|
||||||
|
|
||||||
`order_by(columns: Union[List, str]) -> QuerySet`
|
`order_by(columns: Union[List, str]) -> QuerySet`
|
||||||
|
|
||||||
@ -78,12 +132,14 @@ You can provide a string with field name or list of strings with different field
|
|||||||
|
|
||||||
Ordering in sql will be applied in order of names you provide in order_by.
|
Ordering in sql will be applied in order of names you provide in order_by.
|
||||||
|
|
||||||
!!!tip By default if you do not provide ordering `ormar` explicitly orders by all
|
!!!tip
|
||||||
primary keys
|
By default if you do not provide ordering `ormar` explicitly orders by all
|
||||||
|
primary keys
|
||||||
|
|
||||||
!!!warning If you are sorting by nested models that causes that the result rows are
|
!!!warning
|
||||||
unsorted by the main model
|
If you are sorting by nested models that causes that the result rows are
|
||||||
`ormar` will combine those children rows into one main model.
|
unsorted by the main model
|
||||||
|
`ormar` will combine those children rows into one main model.
|
||||||
|
|
||||||
Sample raw database rows result (sort by child model desc):
|
Sample raw database rows result (sort by child model desc):
|
||||||
```
|
```
|
||||||
@ -103,7 +159,7 @@ unsorted by the main model
|
|||||||
Given sample Models like following:
|
Given sample Models like following:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
--8 < -- "../docs_src/queries/docs007.py"
|
--8 < -- "../../docs_src/queries/docs007.py"
|
||||||
```
|
```
|
||||||
|
|
||||||
To order by main model field just provide a field name
|
To order by main model field just provide a field name
|
||||||
@ -142,10 +198,12 @@ assert owner.toys[0].name == "Toy 4"
|
|||||||
assert owner.toys[1].name == "Toy 1"
|
assert owner.toys[1].name == "Toy 1"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!!note All methods that do not return the rows explicitly returns a QueySet instance so
|
!!!note
|
||||||
you can chain them together
|
All methods that do not return the rows explicitly returns a QueySet instance so
|
||||||
|
you can chain them together
|
||||||
|
|
||||||
So operations like `filter()`, `select_related()`, `limit()` and `offset()` etc. can be chained.
|
So operations like `filter()`, `select_related()`, `limit()` and `offset()` etc. can be chained.
|
||||||
|
|
||||||
Something like `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`
|
Something like `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`
|
||||||
|
|
||||||
|
[querysetproxy]: ../relations/queryset-proxy.md
|
||||||
@ -8,8 +8,9 @@ and it's options.
|
|||||||
Most of the methods are also available through many to many relations and on reverse
|
Most of the methods are also available through many to many relations and on reverse
|
||||||
foreign key relations through `QuerysetProxy` interface.
|
foreign key relations through `QuerysetProxy` interface.
|
||||||
|
|
||||||
!!!info To see which one are supported and how to construct relations
|
!!!info
|
||||||
visit [relations][relations].
|
To see which relations are supported and how to construct relations
|
||||||
|
visit [relations][relations].
|
||||||
|
|
||||||
For simplicity available methods to fetch and save the data into the database are
|
For simplicity available methods to fetch and save the data into the database are
|
||||||
divided into categories according to the function they fulfill.
|
divided into categories according to the function they fulfill.
|
||||||
@ -20,7 +21,7 @@ For complicity also Models and relations methods are listed.
|
|||||||
|
|
||||||
To read more about any specific section or function please refer to the details subpage.
|
To read more about any specific section or function please refer to the details subpage.
|
||||||
|
|
||||||
### Create
|
###[Insert data into database](./create.md)
|
||||||
|
|
||||||
* `create(**kwargs) -> Model`
|
* `create(**kwargs) -> Model`
|
||||||
* `get_or_create(**kwargs) -> Model`
|
* `get_or_create(**kwargs) -> Model`
|
||||||
@ -39,7 +40,7 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy.get_or_create(**kwargs)` method
|
* `QuerysetProxy.get_or_create(**kwargs)` method
|
||||||
* `QuerysetProxy.update_or_create(**kwargs)` method
|
* `QuerysetProxy.update_or_create(**kwargs)` method
|
||||||
|
|
||||||
### Read
|
### [Read data from database](./read.md)
|
||||||
|
|
||||||
* `get(**kwargs) -> Model`
|
* `get(**kwargs) -> Model`
|
||||||
* `get_or_create(**kwargs) -> Model`
|
* `get_or_create(**kwargs) -> Model`
|
||||||
@ -57,7 +58,7 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy.first()` method
|
* `QuerysetProxy.first()` method
|
||||||
* `QuerysetProxy.all(**kwargs)` method
|
* `QuerysetProxy.all(**kwargs)` method
|
||||||
|
|
||||||
### Update
|
### [Update data in database](./update.md)
|
||||||
|
|
||||||
* `update(each: bool = False, **kwargs) -> int`
|
* `update(each: bool = False, **kwargs) -> int`
|
||||||
* `update_or_create(**kwargs) -> Model`
|
* `update_or_create(**kwargs) -> Model`
|
||||||
@ -73,7 +74,7 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy`
|
* `QuerysetProxy`
|
||||||
* `QuerysetProxy.update_or_create(**kwargs)` method
|
* `QuerysetProxy.update_or_create(**kwargs)` method
|
||||||
|
|
||||||
### Delete
|
### [Delete data from database](./delete.md)
|
||||||
|
|
||||||
* `delete(each: bool = False, **kwargs) -> int`
|
* `delete(each: bool = False, **kwargs) -> int`
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy.remove()` method
|
* `QuerysetProxy.remove()` method
|
||||||
* `QuerysetProxy.clear()` method
|
* `QuerysetProxy.clear()` method
|
||||||
|
|
||||||
### Joins and subqueries
|
### [Joins and subqueries](./joins-and-subqueries.md)
|
||||||
|
|
||||||
* `select_related(related: Union[List, str]) -> QuerySet`
|
* `select_related(related: Union[List, str]) -> QuerySet`
|
||||||
* `prefetch_related(related: Union[List, str]) -> QuerySet`
|
* `prefetch_related(related: Union[List, str]) -> QuerySet`
|
||||||
@ -100,7 +101,7 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy.select_related(related: Union[List, str])` method
|
* `QuerysetProxy.select_related(related: Union[List, str])` method
|
||||||
* `QuerysetProxy.prefetch_related(related: Union[List, str])` method
|
* `QuerysetProxy.prefetch_related(related: Union[List, str])` method
|
||||||
|
|
||||||
### Filtering and sorting
|
### [Filtering and sorting](./filter-and-sort.md)
|
||||||
|
|
||||||
* `filter(**kwargs) -> QuerySet`
|
* `filter(**kwargs) -> QuerySet`
|
||||||
* `exclude(**kwargs) -> QuerySet`
|
* `exclude(**kwargs) -> QuerySet`
|
||||||
@ -118,7 +119,7 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy.get_or_create(**kwargs)` method
|
* `QuerysetProxy.get_or_create(**kwargs)` method
|
||||||
* `QuerysetProxy.all(**kwargs)` method
|
* `QuerysetProxy.all(**kwargs)` method
|
||||||
|
|
||||||
### Selecting columns
|
### [Selecting columns](./select-columns.md)
|
||||||
|
|
||||||
* `fields(columns: Union[List, str, set, dict]) -> QuerySet`
|
* `fields(columns: Union[List, str, set, dict]) -> QuerySet`
|
||||||
* `exclude_fields(columns: Union[List, str, set, dict]) -> QuerySet`
|
* `exclude_fields(columns: Union[List, str, set, dict]) -> QuerySet`
|
||||||
@ -128,7 +129,7 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy.fields(columns: Union[List, str, set, dict])` method
|
* `QuerysetProxy.fields(columns: Union[List, str, set, dict])` method
|
||||||
* `QuerysetProxy.exclude_fields(columns: Union[List, str, set, dict])` method
|
* `QuerysetProxy.exclude_fields(columns: Union[List, str, set, dict])` method
|
||||||
|
|
||||||
### Pagination and rows number
|
### [Pagination and rows number](./pagination-and-rows-number.md)
|
||||||
|
|
||||||
* `paginate(page: int) -> QuerySet`
|
* `paginate(page: int) -> QuerySet`
|
||||||
* `limit(limit_count: int) -> QuerySet`
|
* `limit(limit_count: int) -> QuerySet`
|
||||||
@ -142,7 +143,7 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy.limit(limit_count: int)` method
|
* `QuerysetProxy.limit(limit_count: int)` method
|
||||||
* `QuerysetProxy.offset(offset: int)` method
|
* `QuerysetProxy.offset(offset: int)` method
|
||||||
|
|
||||||
### Aggregated functions
|
### [Aggregated functions](./aggregations.md)
|
||||||
|
|
||||||
* `count() -> int`
|
* `count() -> int`
|
||||||
* `exists() -> bool`
|
* `exists() -> bool`
|
||||||
@ -153,4 +154,4 @@ To read more about any specific section or function please refer to the details
|
|||||||
* `QuerysetProxy.exists()` method
|
* `QuerysetProxy.exists()` method
|
||||||
|
|
||||||
|
|
||||||
[relations]: ./relations/index.md
|
[relations]: ../relations/index.md
|
||||||
@ -1,6 +1,18 @@
|
|||||||
# Joins and subqueries
|
# Joins and subqueries
|
||||||
|
|
||||||
|
To join one table to another, so load also related models you can use following methods.
|
||||||
|
|
||||||
|
* `select_related(related: Union[List, str]) -> QuerySet`
|
||||||
|
* `prefetch_related(related: Union[List, str]) -> QuerySet`
|
||||||
|
|
||||||
|
|
||||||
|
* `Model`
|
||||||
|
* `Model.load()` method
|
||||||
|
|
||||||
|
|
||||||
|
* `QuerysetProxy`
|
||||||
|
* `QuerysetProxy.select_related(related: Union[List, str])` method
|
||||||
|
* `QuerysetProxy.prefetch_related(related: Union[List, str])` method
|
||||||
|
|
||||||
## select_related
|
## select_related
|
||||||
|
|
||||||
@ -30,6 +42,30 @@ To chain related `Models` relation use double underscores between names.
|
|||||||
!!!tip
|
!!!tip
|
||||||
To control order of models (both main or nested) use `order_by()` method.
|
To control order of models (both main or nested) use `order_by()` method.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Album(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "albums"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
is_best_seller: bool = ormar.Boolean(default=False)
|
||||||
|
|
||||||
|
class Track(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "tracks"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
album: Optional[Album] = ormar.ForeignKey(Album)
|
||||||
|
title: str = ormar.String(max_length=100)
|
||||||
|
position: int = ormar.Integer()
|
||||||
|
play_count: int = ormar.Integer(nullable=True)
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
album = await Album.objects.select_related("tracks").all()
|
album = await Album.objects.select_related("tracks").all()
|
||||||
# will return album will all columns tracks
|
# will return album will all columns tracks
|
||||||
@ -37,6 +73,52 @@ album = await Album.objects.select_related("tracks").all()
|
|||||||
|
|
||||||
You can provide a string or a list of strings
|
You can provide a string or a list of strings
|
||||||
|
|
||||||
|
```python
|
||||||
|
class SchoolClass(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "schoolclasses"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
department: Optional[Department] = ormar.ForeignKey(Department, nullable=False)
|
||||||
|
|
||||||
|
|
||||||
|
class Category(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "categories"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
|
||||||
|
|
||||||
|
class Student(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "students"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
schoolclass: Optional[SchoolClass] = ormar.ForeignKey(SchoolClass)
|
||||||
|
category: Optional[Category] = ormar.ForeignKey(Category, nullable=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Teacher(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "teachers"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
schoolclass: Optional[SchoolClass] = ormar.ForeignKey(SchoolClass)
|
||||||
|
category: Optional[Category] = ormar.ForeignKey(Category, nullable=True)
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
classes = await SchoolClass.objects.select_related(
|
classes = await SchoolClass.objects.select_related(
|
||||||
["teachers__category", "students"]).all()
|
["teachers__category", "students"]).all()
|
||||||
@ -81,12 +163,82 @@ To chain related `Models` relation use double underscores between names.
|
|||||||
!!!tip
|
!!!tip
|
||||||
To control order of models (both main or nested) use `order_by()` method.
|
To control order of models (both main or nested) use `order_by()` method.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Album(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "albums"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
is_best_seller: bool = ormar.Boolean(default=False)
|
||||||
|
|
||||||
|
class Track(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "tracks"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
album: Optional[Album] = ormar.ForeignKey(Album)
|
||||||
|
title: str = ormar.String(max_length=100)
|
||||||
|
position: int = ormar.Integer()
|
||||||
|
play_count: int = ormar.Integer(nullable=True)
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
album = await Album.objects.prefetch_related("tracks").all()
|
album = await Album.objects.prefetch_related("tracks").all()
|
||||||
# will return album will all columns tracks
|
# will return album will all columns tracks
|
||||||
```
|
```
|
||||||
|
|
||||||
You can provide a string or a list of strings
|
You can provide a string, or a list of strings
|
||||||
|
|
||||||
|
```python
|
||||||
|
class SchoolClass(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "schoolclasses"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
department: Optional[Department] = ormar.ForeignKey(Department, nullable=False)
|
||||||
|
|
||||||
|
|
||||||
|
class Category(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "categories"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
|
||||||
|
|
||||||
|
class Student(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "students"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
schoolclass: Optional[SchoolClass] = ormar.ForeignKey(SchoolClass)
|
||||||
|
category: Optional[Category] = ormar.ForeignKey(Category, nullable=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Teacher(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "teachers"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
schoolclass: Optional[SchoolClass] = ormar.ForeignKey(SchoolClass)
|
||||||
|
category: Optional[Category] = ormar.ForeignKey(Category, nullable=True)
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
classes = await SchoolClass.objects.prefetch_related(
|
classes = await SchoolClass.objects.prefetch_related(
|
||||||
@ -221,3 +373,44 @@ That means that in `prefetch_related` example above if there are 3 distinct mode
|
|||||||
table B and 2 in table C, there will be only 5 children nested models shared between all
|
table B and 2 in table C, there will be only 5 children nested models shared between all
|
||||||
model A instances. That also means that if you update any attribute it will be updated
|
model A instances. That also means that if you update any attribute it will be updated
|
||||||
on all parents as they share the same child object.
|
on all parents as they share the same child object.
|
||||||
|
|
||||||
|
|
||||||
|
## Model methods
|
||||||
|
|
||||||
|
Each model instance have a set of methods to `save`, `update` or `load` itself.
|
||||||
|
|
||||||
|
### load
|
||||||
|
|
||||||
|
You can load the `ForeignKey` related model by calling `load()` method.
|
||||||
|
|
||||||
|
`load()` can be used to refresh the model from the database (if it was changed by some other process).
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
Read more about `load()` method in [models methods](../models/methods.md#load)
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
### select_related
|
||||||
|
|
||||||
|
Works exactly the same as [select_related](./#select_related) function above but allows you to fetch related
|
||||||
|
objects from other side of the relation.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
To read more about `QuerysetProxy` visit [querysetproxy][querysetproxy] section
|
||||||
|
|
||||||
|
### prefetch_related
|
||||||
|
|
||||||
|
Works exactly the same as [prefetch_related](./#prefetch_related) function above but allows you to fetch related
|
||||||
|
objects from other side of the relation.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
To read more about `QuerysetProxy` visit [querysetproxy][querysetproxy] section
|
||||||
|
|
||||||
|
|
||||||
|
[querysetproxy]: ../relations/queryset-proxy.md
|
||||||
@ -1,29 +1,57 @@
|
|||||||
# Read/ Load data from database
|
# Read data from database
|
||||||
|
|
||||||
* `get(**kwargs): -> Model`
|
Following methods allow you to load data from the database.
|
||||||
|
|
||||||
|
* `get(**kwargs) -> Model`
|
||||||
* `get_or_create(**kwargs) -> Model`
|
* `get_or_create(**kwargs) -> Model`
|
||||||
* `first(): -> Model`
|
* `first() -> Model`
|
||||||
* `all(**kwargs) -> List[Optional[Model]]`
|
* `all(**kwargs) -> List[Optional[Model]]`
|
||||||
* `Model.load() method`
|
|
||||||
|
|
||||||
|
* `Model`
|
||||||
|
* `Model.load()` method
|
||||||
|
|
||||||
|
|
||||||
|
* `QuerysetProxy`
|
||||||
|
* `QuerysetProxy.get(**kwargs)` method
|
||||||
|
* `QuerysetProxy.get_or_create(**kwargs)` method
|
||||||
|
* `QuerysetProxy.first()` method
|
||||||
|
* `QuerysetProxy.all(**kwargs)` method
|
||||||
|
|
||||||
## get
|
## get
|
||||||
|
|
||||||
`get(**kwargs): -> Model`
|
`get(**kwargs) -> Model`
|
||||||
|
|
||||||
Get's the first row from the db meeting the criteria set by kwargs.
|
Get's the first row from the db meeting the criteria set by kwargs.
|
||||||
|
|
||||||
If no criteria set it will return the last row in db sorted by pk.
|
If no criteria set it will return the last row in db sorted by pk column.
|
||||||
|
|
||||||
Passing a criteria is actually calling filter(**kwargs) method described below.
|
Passing a criteria is actually calling filter(**kwargs) method described below.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Track(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "track"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
album: Optional[Album] = ormar.ForeignKey(Album)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
position: int = ormar.Integer()
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
track = await Track.objects.get(name='The Bird')
|
track = await Track.objects.get(name='The Bird')
|
||||||
# note that above is equivalent to await Track.objects.filter(name='The Bird').get()
|
# note that above is equivalent to await Track.objects.filter(name='The Bird').get()
|
||||||
track2 = track = await Track.objects.get()
|
track2 = track = await Track.objects.get()
|
||||||
track == track2 # True since it's the only row in db in our example
|
track == track2
|
||||||
|
# True since it's the only row in db in our example
|
||||||
|
# and get without arguments return first row by pk column desc
|
||||||
```
|
```
|
||||||
|
|
||||||
!!!warning If no row meets the criteria `NoMatch` exception is raised.
|
!!!warning
|
||||||
|
If no row meets the criteria `NoMatch` exception is raised.
|
||||||
|
|
||||||
If there are multiple rows meeting the criteria the `MultipleMatches` exception is raised.
|
If there are multiple rows meeting the criteria the `MultipleMatches` exception is raised.
|
||||||
|
|
||||||
@ -36,6 +64,17 @@ Combination of create and get methods.
|
|||||||
Tries to get a row meeting the criteria and if `NoMatch` exception is raised it creates
|
Tries to get a row meeting the criteria and if `NoMatch` exception is raised it creates
|
||||||
a new one with given kwargs.
|
a new one with given kwargs.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Album(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "album"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
album = await Album.objects.get_or_create(name='The Cat')
|
album = await Album.objects.get_or_create(name='The Cat')
|
||||||
# object is created as it does not exist
|
# object is created as it does not exist
|
||||||
@ -44,20 +83,41 @@ assert album == album2
|
|||||||
# return True as the same db row is returned
|
# return True as the same db row is returned
|
||||||
```
|
```
|
||||||
|
|
||||||
!!!warning Despite being a equivalent row from database the `album` and `album2` in
|
!!!warning
|
||||||
example above are 2 different python objects!
|
Despite being an equivalent row from database the `album` and `album2` in
|
||||||
Updating one of them will not refresh the second one until you excplicitly load() the
|
example above are 2 different python objects!
|
||||||
fresh data from db.
|
Updating one of them will not refresh the second one until you excplicitly load() the
|
||||||
|
fresh data from db.
|
||||||
|
|
||||||
!!!note Note that if you want to create a new object you either have to pass pk column
|
!!!note
|
||||||
value or pk column has to be set as autoincrement
|
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
|
||||||
|
|
||||||
## first
|
## first
|
||||||
|
|
||||||
`first(): -> Model`
|
`first() -> Model`
|
||||||
|
|
||||||
Gets the first row from the db ordered by primary key column ascending.
|
Gets the first row from the db ordered by primary key column ascending.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Album(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "album"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
await Album.objects.create(name='The Cat')
|
||||||
|
await Album.objects.create(name='The Dog')
|
||||||
|
album = await Album.objects.first()
|
||||||
|
# first row by primary_key column asc
|
||||||
|
assert album.name == 'The Cat'
|
||||||
|
```
|
||||||
|
|
||||||
## all
|
## all
|
||||||
|
|
||||||
`all(**kwargs) -> List[Optional["Model"]]`
|
`all(**kwargs) -> List[Optional["Model"]]`
|
||||||
@ -69,12 +129,90 @@ Passing kwargs is a shortcut and equals to calling `filter(**kwrags).all()`.
|
|||||||
If there are no rows meeting the criteria an empty list is returned.
|
If there are no rows meeting the criteria an empty list is returned.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
tracks = await Track.objects.select_related("album").all(title='Sample')
|
class Album(ormar.Model):
|
||||||
# will return a list of all Tracks with title Sample
|
class Meta:
|
||||||
|
tablename = "album"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
name: str = ormar.String(max_length=100)
|
||||||
|
|
||||||
|
|
||||||
|
class Track(ormar.Model):
|
||||||
|
class Meta:
|
||||||
|
tablename = "track"
|
||||||
|
metadata = metadata
|
||||||
|
database = database
|
||||||
|
|
||||||
|
id: int = ormar.Integer(primary_key=True)
|
||||||
|
album: Optional[Album] = ormar.ForeignKey(Album)
|
||||||
|
title: str = ormar.String(max_length=100)
|
||||||
|
position: int = ormar.Integer()
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
tracks = await Track.objects.select_related("album").all(album__title='Sample')
|
||||||
|
# will return a list of all Tracks for album Sample
|
||||||
|
# for more on joins visit joining and subqueries section
|
||||||
|
|
||||||
tracks = await Track.objects.all()
|
tracks = await Track.objects.all()
|
||||||
# will return a list of all Tracks in database
|
# will return a list of all Tracks in database
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Model method
|
## Model methods
|
||||||
|
|
||||||
|
Each model instance have a set of methods to `save`, `update` or `load` itself.
|
||||||
|
|
||||||
|
### load
|
||||||
|
|
||||||
|
You can load the `ForeignKey` related model by calling `load()` method.
|
||||||
|
|
||||||
|
`load()` can be used to refresh the model from the database (if it was changed by some other process).
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
Read more about `load()` method in [models methods](../models/methods.md#load)
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
### get
|
||||||
|
|
||||||
|
Works exactly the same as [get](./#get) function above but allows you to fetch related
|
||||||
|
objects from other side of the relation.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
To read more about `QuerysetProxy` visit [querysetproxy][querysetproxy] section
|
||||||
|
|
||||||
|
### get_or_create
|
||||||
|
|
||||||
|
Works exactly the same as [get_or_create](./#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][querysetproxy] section
|
||||||
|
|
||||||
|
### first
|
||||||
|
|
||||||
|
Works exactly the same as [first](./#first) function above but allows you to query
|
||||||
|
related objects from other side of the relation.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
To read more about `QuerysetProxy` visit [querysetproxy][querysetproxy] section
|
||||||
|
|
||||||
|
### all
|
||||||
|
|
||||||
|
Works exactly the same as [all](./#all) function above but allows you to query related
|
||||||
|
objects from other side of the relation.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
To read more about `QuerysetProxy` visit [querysetproxy][querysetproxy] section
|
||||||
|
|
||||||
|
|
||||||
|
[querysetproxy]: ../relations/queryset-proxy.md
|
||||||
@ -1,11 +1,20 @@
|
|||||||
# Update
|
# Update data in database
|
||||||
|
|
||||||
|
Following methods and functions allow updating existing data in the database.
|
||||||
|
|
||||||
* `update(each: bool = False, **kwargs) -> int`
|
* `update(each: bool = False, **kwargs) -> int`
|
||||||
* `update_or_create(**kwargs) -> Model`
|
* `update_or_create(**kwargs) -> Model`
|
||||||
* `bulk_update(objects: List[Model], columns: List[str] = None) -> None`
|
* `bulk_update(objects: List[Model], columns: List[str] = None) -> None`
|
||||||
* `Model.update() method`
|
|
||||||
* `Model.upsert() method`
|
|
||||||
* `Model.save_related() method`
|
* `Model`
|
||||||
|
* `Model.update()` method
|
||||||
|
* `Model.upsert()` method
|
||||||
|
* `Model.save_related()` method
|
||||||
|
|
||||||
|
|
||||||
|
* `QuerysetProxy`
|
||||||
|
* `QuerysetProxy.update_or_create(**kwargs)` method
|
||||||
|
|
||||||
## update
|
## update
|
||||||
|
|
||||||
@ -24,8 +33,8 @@ Return number of rows updated.
|
|||||||
--8<-- "../docs_src/queries/docs002.py"
|
--8<-- "../docs_src/queries/docs002.py"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!!warning Queryset needs to be filtered before updating to prevent accidental
|
!!!warning
|
||||||
overwrite.
|
Queryset needs to be filtered before updating to prevent accidental overwrite.
|
||||||
|
|
||||||
To update whole database table `each=True` needs to be provided as a safety switch
|
To update whole database table `each=True` needs to be provided as a safety switch
|
||||||
|
|
||||||
@ -39,8 +48,9 @@ Updates the model, or in case there is no match in database creates a new one.
|
|||||||
--8<-- "../docs_src/queries/docs003.py"
|
--8<-- "../docs_src/queries/docs003.py"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!!note Note that if you want to create a new object you either have to pass pk column
|
!!!note
|
||||||
value or pk column has to be set as autoincrement
|
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_update
|
## bulk_update
|
||||||
|
|
||||||
@ -67,5 +77,50 @@ completed = await ToDo.objects.filter(completed=False).all()
|
|||||||
assert len(completed) == 3
|
assert len(completed) == 3
|
||||||
```
|
```
|
||||||
|
|
||||||
## Model method
|
## Model methods
|
||||||
|
|
||||||
|
Each model instance have a set of methods to `save`, `update` or `load` itself.
|
||||||
|
|
||||||
|
###update
|
||||||
|
|
||||||
|
You can update models by updating your model attributes (fields) and calling `update()` method.
|
||||||
|
|
||||||
|
If you try to update a model without a primary key set a `ModelPersistenceError` exception will be thrown.
|
||||||
|
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
Read more about `update()` method in [models-update](../models/methods.md#update)
|
||||||
|
|
||||||
|
###upsert
|
||||||
|
|
||||||
|
It's a proxy to either `save()` or `update(**kwargs)` methods of a Model.
|
||||||
|
If the pk is set the `update()` method will be called.
|
||||||
|
|
||||||
|
!!!tip
|
||||||
|
Read more about `upsert()` method in [models-upsert][models-upsert]
|
||||||
|
|
||||||
|
###save_related
|
||||||
|
|
||||||
|
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][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.
|
||||||
|
|
||||||
|
### update_or_create
|
||||||
|
|
||||||
|
Works exactly the same as [update_or_create](./#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][querysetproxy] section
|
||||||
|
|
||||||
|
[querysetproxy]: ../relations/queryset-proxy.md
|
||||||
|
[models-upsert]: ../models/methods.md#upsert
|
||||||
|
[models-save-related]: ../models/methods.md#save_related
|
||||||
@ -84,9 +84,9 @@ nav:
|
|||||||
- Exceptions: api/exceptions.md
|
- Exceptions: api/exceptions.md
|
||||||
repo_name: collerek/ormar
|
repo_name: collerek/ormar
|
||||||
repo_url: https://github.com/collerek/ormar
|
repo_url: https://github.com/collerek/ormar
|
||||||
google_analytics:
|
#google_analytics:
|
||||||
- UA-72514911-3
|
# - UA-72514911-3
|
||||||
- auto
|
# - auto
|
||||||
theme:
|
theme:
|
||||||
name: material
|
name: material
|
||||||
highlightjs: true
|
highlightjs: true
|
||||||
|
|||||||
Reference in New Issue
Block a user