next part of the docs and api documentation in beta ver

This commit is contained in:
collerek
2021-01-04 19:38:21 +01:00
parent eec17e2f78
commit 9f8e8e87e8
64 changed files with 7414 additions and 37 deletions

View File

@ -0,0 +1,64 @@
<a name="models.helpers.models"></a>
# models.helpers.models
<a name="models.helpers.models.populate_default_options_values"></a>
#### populate\_default\_options\_values
```python
populate_default_options_values(new_model: Type["Model"], model_fields: Dict) -> None
```
Sets all optional Meta values to it's defaults
and set model_fields that were already previously extracted.
Here should live all options that are not overwritten/set for all models.
Current options are:
* constraints = []
* abstract = False
**Arguments**:
- `new_model (Model class)`: newly constructed Model
- `model_fields (Union[Dict[str, type], Dict])`:
<a name="models.helpers.models.extract_annotations_and_default_vals"></a>
#### extract\_annotations\_and\_default\_vals
```python
extract_annotations_and_default_vals(attrs: Dict) -> Tuple[Dict, Dict]
```
Extracts annotations from class namespace dict and triggers
extraction of ormar model_fields.
**Arguments**:
- `attrs (Dict)`: namespace of the class created
**Returns**:
`(Tuple[Dict, Dict])`: namespace of the class updated, dict of extracted model_fields
<a name="models.helpers.models.validate_related_names_in_relations"></a>
#### validate\_related\_names\_in\_relations
```python
validate_related_names_in_relations(model_fields: Dict, new_model: Type["Model"]) -> None
```
Performs a validation of relation_names in relation fields.
If multiple fields are leading to the same related model
only one can have empty related_name param
(populated by default as model.name.lower()+'s').
Also related_names have to be unique for given related model.
**Raises**:
- `ModelDefinitionError`: if validation of related_names fail
**Arguments**:
- `model_fields (Dict[str, ormar.Field])`: dictionary of declared ormar model fields
- `new_model (Model class)`:

View File

@ -0,0 +1,122 @@
<a name="models.helpers.pydantic"></a>
# models.helpers.pydantic
<a name="models.helpers.pydantic.create_pydantic_field"></a>
#### create\_pydantic\_field
```python
create_pydantic_field(field_name: str, model: Type["Model"], model_field: Type[ManyToManyField]) -> None
```
Registers pydantic field on through model that leads to passed model
and is registered as field_name passed.
Through model is fetched from through attributed on passed model_field.
**Arguments**:
- `field_name (str)`: field name to register
- `model (Model class)`: type of field to register
- `model_field (ManyToManyField class)`: relation field from which through model is extracted
<a name="models.helpers.pydantic.get_pydantic_field"></a>
#### get\_pydantic\_field
```python
get_pydantic_field(field_name: str, model: Type["Model"]) -> "ModelField"
```
Extracts field type and if it's required from Model model_fields by passed
field_name. Returns a pydantic field with type of field_name field type.
**Arguments**:
- `field_name (str)`: field name to fetch from Model and name of pydantic field
- `model (Model class)`: type of field to register
**Returns**:
`(pydantic.ModelField)`: newly created pydantic field
<a name="models.helpers.pydantic.populate_default_pydantic_field_value"></a>
#### populate\_default\_pydantic\_field\_value
```python
populate_default_pydantic_field_value(ormar_field: Type[BaseField], field_name: str, attrs: dict) -> dict
```
Grabs current value of the ormar Field in class namespace
(so the default_value declared on ormar model if set)
and converts it to pydantic.FieldInfo
that pydantic is able to extract later.
On FieldInfo there are saved all needed params like max_length of the string
and other constraints that pydantic can use to build
it's own field validation used by ormar.
**Arguments**:
- `ormar_field (ormar Field)`: field to convert
- `field_name (str)`: field to convert name
- `attrs (Dict)`: current class namespace
**Returns**:
`(Dict)`: updated namespace dict
<a name="models.helpers.pydantic.populate_pydantic_default_values"></a>
#### populate\_pydantic\_default\_values
```python
populate_pydantic_default_values(attrs: Dict) -> Tuple[Dict, Dict]
```
Extracts ormar fields from annotations (deprecated) and from namespace
dictionary of the class. Fields declared on model are all subclasses of the
BaseField class.
Trigger conversion of ormar field into pydantic FieldInfo, which has all needed
paramaters saved.
Overwrites the annotations of ormar fields to corresponding types declared on
ormar fields (constructed dynamically for relations).
Those annotations are later used by pydantic to construct it's own fields.
**Arguments**:
- `attrs (Dict)`: current class namespace
**Returns**:
`(Tuple[Dict, Dict])`: namespace of the class updated, dict of extracted model_fields
<a name="models.helpers.pydantic.get_pydantic_base_orm_config"></a>
#### get\_pydantic\_base\_orm\_config
```python
get_pydantic_base_orm_config() -> Type[BaseConfig]
```
Returns empty pydantic Config with orm_mode set to True.
**Returns**:
`(pydantic Config)`: empty default config with orm_mode set.
<a name="models.helpers.pydantic.get_potential_fields"></a>
#### get\_potential\_fields
```python
get_potential_fields(attrs: Dict) -> Dict
```
Gets all the fields in current class namespace that are Fields.
**Arguments**:
- `attrs (Dict)`: current class namespace
**Returns**:
`(Dict)`: extracted fields that are ormar Fields

View File

@ -0,0 +1,154 @@
<a name="models.helpers.relations"></a>
# models.helpers.relations
<a name="models.helpers.relations.alias_manager"></a>
#### alias\_manager
<a name="models.helpers.relations.register_relation_on_build"></a>
#### register\_relation\_on\_build
```python
register_relation_on_build(new_model: Type["Model"], field_name: str) -> None
```
Registers ForeignKey relation in alias_manager to set a table_prefix.
Registration include also reverse relation side to be able to join both sides.
Relation is registered by model name and relation field name to allow for multiple
relations between two Models that needs to have different
aliases for proper sql joins.
**Arguments**:
- `new_model (Model class)`: constructed model
- `field_name (str)`: name of the related field
<a name="models.helpers.relations.register_many_to_many_relation_on_build"></a>
#### register\_many\_to\_many\_relation\_on\_build
```python
register_many_to_many_relation_on_build(new_model: Type["Model"], field: Type[ManyToManyField], field_name: str) -> None
```
Registers connection between through model and both sides of the m2m relation.
Registration include also reverse relation side to be able to join both sides.
Relation is registered by model name and relation field name to allow for multiple
relations between two Models that needs to have different
aliases for proper sql joins.
By default relation name is a model.name.lower().
**Arguments**:
- `field_name (str)`: name of the relation key
- `new_model (Model class)`: model on which m2m field is declared
- `field (ManyToManyField class)`: relation field
<a name="models.helpers.relations.expand_reverse_relationships"></a>
#### expand\_reverse\_relationships
```python
expand_reverse_relationships(model: Type["Model"]) -> None
```
Iterates through model_fields of given model and verifies if all reverse
relation have been populated on related models.
If the reverse relation has not been set before it's set here.
**Arguments**:
- `model (Model class)`: model on which relation should be checked and registered
<a name="models.helpers.relations.register_reverse_model_fields"></a>
#### register\_reverse\_model\_fields
```python
register_reverse_model_fields(model: Type["Model"], child: Type["Model"], related_name: str, model_field: Type["ForeignKeyField"]) -> None
```
Registers reverse ForeignKey field on related model.
By default it's name.lower()+'s' of the model on which relation is defined.
But if the related_model name is provided it's registered with that name.
Autogenerated reverse fields also set related_name to the original field name.
**Arguments**:
- `model (Model class)`: related model on which reverse field should be defined
- `child (Model class)`: parent model with relation definition
- `related_name (str)`: name by which reverse key should be registered
- `model_field (relation Field)`: original relation ForeignKey field
<a name="models.helpers.relations.register_relation_in_alias_manager"></a>
#### register\_relation\_in\_alias\_manager
```python
register_relation_in_alias_manager(new_model: Type["Model"], field: Type[ForeignKeyField], field_name: str) -> None
```
Registers the relation (and reverse relation) in alias manager.
The m2m relations require registration of through model between
actual end models of the relation.
Delegates the actual registration to:
m2m - register_many_to_many_relation_on_build
fk - register_relation_on_build
**Arguments**:
- `new_model (Model class)`: model on which relation field is declared
- `field (ForeignKey or ManyToManyField class)`: relation field
- `field_name (str)`: name of the relation key
<a name="models.helpers.relations.verify_related_name_dont_duplicate"></a>
#### verify\_related\_name\_dont\_duplicate
```python
verify_related_name_dont_duplicate(child: Type["Model"], parent_model: Type["Model"], related_name: str) -> None
```
Verifies whether the used related_name (regardless of the fact if user defined or
auto generated) is already used on related model, but is connected with other model
than the one that we connect right now.
**Raises**:
- `ModelDefinitionError`: if name is already used but lead to different related
model
**Arguments**:
- `child (ormar.models.metaclass.ModelMetaclass)`: related Model class
- `parent_model (ormar.models.metaclass.ModelMetaclass)`: parent Model class
- `related_name ()`:
**Returns**:
`(None)`: None
<a name="models.helpers.relations.reverse_field_not_already_registered"></a>
#### reverse\_field\_not\_already\_registered
```python
reverse_field_not_already_registered(child: Type["Model"], child_model_name: str, parent_model: Type["Model"]) -> bool
```
Checks if child is already registered in parents pydantic fields.
**Raises**:
- `ModelDefinitionError`: if related name is already used but lead to different
related model
**Arguments**:
- `child (ormar.models.metaclass.ModelMetaclass)`: related Model class
- `child_model_name (str)`: related_name of the child if provided
- `parent_model (ormar.models.metaclass.ModelMetaclass)`: parent Model class
**Returns**:
`(bool)`: result of the check

View File

@ -0,0 +1,145 @@
<a name="models.helpers.sqlalchemy"></a>
# models.helpers.sqlalchemy
<a name="models.helpers.sqlalchemy.adjust_through_many_to_many_model"></a>
#### adjust\_through\_many\_to\_many\_model
```python
adjust_through_many_to_many_model(model: Type["Model"], child: Type["Model"], model_field: Type[ManyToManyField]) -> None
```
Registers m2m relation on through model.
Sets ormar.ForeignKey from through model to both child and parent models.
Sets sqlalchemy.ForeignKey to both child and parent models.
Sets pydantic fields with child and parent model types.
**Arguments**:
- `model (Model class)`: model on which relation is declared
- `child (Model class)`: model to which m2m relation leads
- `model_field (ManyToManyField)`: relation field defined in parent model
<a name="models.helpers.sqlalchemy.create_and_append_m2m_fk"></a>
#### create\_and\_append\_m2m\_fk
```python
create_and_append_m2m_fk(model: Type["Model"], model_field: Type[ManyToManyField]) -> None
```
Registers sqlalchemy Column with sqlalchemy.ForeignKey leadning to the model.
Newly created field is added to m2m relation through model Meta columns and table.
**Arguments**:
- `model (Model class)`: Model class to which FK should be created
- `model_field (ManyToManyField field)`: field with ManyToMany relation
<a name="models.helpers.sqlalchemy.check_pk_column_validity"></a>
#### check\_pk\_column\_validity
```python
check_pk_column_validity(field_name: str, field: BaseField, pkname: Optional[str]) -> Optional[str]
```
Receives the field marked as primary key and verifies if the pkname
was not already set (only one allowed per model) and if field is not marked
as pydantic_only as it needs to be a database field.
**Raises**:
- `ModelDefintionError`: if pkname already set or field is pydantic_only
**Arguments**:
- `field_name (str)`: name of field
- `field (BaseField)`: ormar.Field
- `pkname (Optional[str])`: already set pkname
**Returns**:
`(str)`: name of the field that should be set as pkname
<a name="models.helpers.sqlalchemy.sqlalchemy_columns_from_model_fields"></a>
#### sqlalchemy\_columns\_from\_model\_fields
```python
sqlalchemy_columns_from_model_fields(model_fields: Dict, new_model: Type["Model"]) -> Tuple[Optional[str], List[sqlalchemy.Column]]
```
Iterates over declared on Model model fields and extracts fields that
should be treated as database fields.
If the model is empty it sets mandatory id field as primary key
(used in through models in m2m relations).
Triggers a validation of relation_names in relation fields. If multiple fields
are leading to the same related model only one can have empty related_name param.
Also related_names have to be unique.
Trigger validation of primary_key - only one and required pk can be set,
cannot be pydantic_only.
Append fields to columns if it's not pydantic_only,
virtual ForeignKey or ManyToMany field.
**Raises**:
- `ModelDefinitionError`: if validation of related_names fail,
or pkname validation fails.
**Arguments**:
- `model_fields (Dict[str, ormar.Field])`: dictionary of declared ormar model fields
- `new_model (Model class)`:
**Returns**:
`(Tuple[Optional[str], List[sqlalchemy.Column]])`: pkname, list of sqlalchemy columns
<a name="models.helpers.sqlalchemy.populate_meta_tablename_columns_and_pk"></a>
#### populate\_meta\_tablename\_columns\_and\_pk
```python
populate_meta_tablename_columns_and_pk(name: str, new_model: Type["Model"]) -> Type["Model"]
```
Sets Model tablename if it's not already set in Meta.
Default tablename if not present is class name lower + s (i.e. Bed becomes -> beds)
Checks if Model's Meta have pkname and columns set.
If not calls the sqlalchemy_columns_from_model_fields to populate
columns from ormar.fields definitions.
**Raises**:
- `ModelDefinitionError`: if pkname is not present raises ModelDefinitionError.
Each model has to have pk.
**Arguments**:
- `name (str)`: name of the current Model
- `new_model (ormar.models.metaclass.ModelMetaclass)`: currently constructed Model
**Returns**:
`(ormar.models.metaclass.ModelMetaclass)`: Model with populated pkname and columns in Meta
<a name="models.helpers.sqlalchemy.populate_meta_sqlalchemy_table_if_required"></a>
#### populate\_meta\_sqlalchemy\_table\_if\_required
```python
populate_meta_sqlalchemy_table_if_required(meta: "ModelMeta") -> None
```
Constructs sqlalchemy table out of columns and parameters set on Meta class.
It populates name, metadata, columns and constraints.
**Arguments**:
- `meta (Model class Meta)`: Meta class of the Model without sqlalchemy table constructed
**Returns**:
`(Model class)`: class with populated Meta.table