Modèle
Définir un modèle
En définissant un modèle ormar, vous obtenez gratuitement le modèle Pydantic correspondant ainsi que les tables Sqlalchemy. elles sont gérées en arrière-plan et vous n'avez pas à les créer vous-même.
Classe de modèle
Pour construire un modèle ormar, il vous suffit d'hériter de la classe ormar.Model.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Définir un terrain
Ensuite, un ou plusieurs champs sont affectés en tant que variables de niveau classe.
Types de champs basiques
Chaque table doit avoir une colonne de clé primaire, que vous pouvez spécifier en définissant Primary_key=True sur le champ sélectionné.
Une seule colonne de clé primaire est autorisée.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!Attention Ne pas affecter la colonne Primary_key ou affecter plusieurs colonnes à chaque modèle lève une exception ModelDefinitionError.
Par défaut, si vous affectez une clé primaire à un champ entier, l'option incrémentation automatique est définie sur true.
Vous pouvez le désactiver en passant autoincrement=False.
| id: int = ormar.Integer(primary_key=True, autoincrement=False)
|
Champs non-base de données
Notez que si vous avez besoin d'un champ pydantique normal dans votre modèle (pour stocker des valeurs sur le modèle ou pour passer certaines valeurs), vous pouvez définir un champ dans pydantic comme vous le feriez normalement.
Les champs ainsi créés sont ajoutés aux champs du modèle pydantique-> et sont donc validés en fonction du type de champ, et apparaissent également dans les résultats de model_dump() et model_dump_json().
La différence est que ces champs ne sont pas enregistrés dans la base de données, ils ne sont donc pas inclus dans la colonne sqlalchemy sous-jacente ou dans les variables de table (consultez la section interne ci-dessous pour savoir comment y accéder si nécessaire).
Par la suite, le champ pydantique ne sera pas inclus dans la migration ou dans toute opération de base de données telle que la sauvegarde, la mise à jour, etc.
Des champs comme celui-ci peuvent être passés dans la charge utile de la requête fastapi et seront retournés dans la réponse fastapi (uniquement si vous avez défini leur valeur quelque part dans le code, bien sûr, car la valeur n'a pas été obtenue à partir de la base de données. si vous passez une valeur dans fastapirequest et renvoyez la même instance que fastapi a construite pour vous dans le modèle de requête_, vous devriez renvoyer exactement la même valeur dans la réponse.)
!!! Le champ pydantique doit toujours être facultatif et ne peut pas être modifié (sinon la validation du chargement de la base de données échouera).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | import databases
import ormar
import pydantic
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
non_db_field: str = pydantic.Field(max_length=100)
|
Si vous définissez le champ pydantic avec les paramètres par défaut et ne passez pas la valeur réelle dans la requête, vous obtiendrez toujours la valeur par défaut. Comme il peut s'agir d'une fonction, vous pouvez définir default= datetime.datetime.now et obtenir l'horodatage actuel chaque fois que vous appelez le point final, etc.
Champs non-base de données dans Fastapi
Notez que les champs de décoration pydantic et calculated_fields peuvent être inclus/exclus des réponses model_dump() et fastapi, incluant/excluant et response_model_include/response_model_exclude en conséquence.
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 | # <== partie du code relatif supprimé pour clarté ==>
base_ormar_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL),
metadata=sqlalchemy.MetaData(),
engine=sqlalchemy.create_engine(DATABASE_URL),
)
Classe Utilisateur (modèle ormar):
ormar_config = base_ormar_config.copy(tablename="users2")
id: int = ormar.Integer(primary_key=True)
Email: str = ormar.String(max_length=255, nullable=False)
password: str = ormar.String(max_length=255)
first_name: str = ormar.String(max_length=255)
last_name: str = ormar.String(max_length=255)
catégorie: str = ormar.String(max_length=255, nullable=True)
timestamp: datetime.datetime = pydantic.Field(
default= datetime.datetime.now
)
# <== partie du code relatif supprimé pour clarté ==>
app = FastAPI()
@ app.post ("/users/")
async def create_user(user: User):
return await user.save ()
# <== partie du code relatif supprimé pour clarté ==>
def test_excluding_fields_in_endpoints():
client = TestClient(app)
Avec un client comme client:
timestamp = datetime.datetime.now ()
user = {
"email": "test@domain.com",
"password": "^*^%A*DA*IAAA",
"first_name": "John",
"last_name": "Doe",
« timestamp »: str(timestamp),
}
response = client.post ("/users/", json=user)
assert list(response.json().keys())= [
« ID »,
« Email »,
"premier_nom",
"dernier_nom",
"Catégorie",
« Timestamp »,
]
# Returned est le même moment
assert response.json().get("timestamp") == str(timestamp).replace(" ", "T")
# <== partie du code relatif supprimé pour clarté ==>
|
Nom du champ vs nom de la colonne
Par défaut, le nom du champ sera utilisé pour le modèle pydantique sous-jacent et la table sqlalchemy.
Si, pour une raison quelconque, vous souhaitez modifier le nom dans la base de données mais le conserver dans le modèle, vous pouvez le faire en spécifiant un paramètre de nom lors de la déclaration de champ.
Voici un exemple de modèle dont le nom a changé
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import databases
import ormar
import sqlalchemy
DATABASE_URl = "sqlite:///test.db"
database = databases.Database(DATABASE_URl, force_rollback=True)
metadata = sqlalchemy.MetaData()
class Child(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="children",
)
id: int = ormar.Integer(name="child_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
born_year: int = ormar.Integer(name="year_born", nullable=True)
|
Notez que vous pouvez également changer le nom de la colonne de clé étrangère
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 | from typing import Optional
import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///test.db", force_rollback=True)
metadata = sqlalchemy.MetaData()
class Artist(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="artists",
)
id: int = ormar.Integer(name="artist_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
born_year: int = ormar.Integer(name="year")
class Album(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="music_albums",
)
id: int = ormar.Integer(name="album_id", primary_key=True)
name: str = ormar.String(name="album_name", max_length=100)
artist: Optional[Artist] = ormar.ForeignKey(Artist, name="artist_id")
|
Mais pour le moment, vous ne pouvez pas modifier les noms des colonnes ManyToMany, car elles passeront par d'autres modèles de toute façon.
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 | import databases
import ormar
import sqlalchemy
DATABASE_URl = "sqlite:///test.db"
database = databases.Database(DATABASE_URl, force_rollback=True)
metadata = sqlalchemy.MetaData()
class Child(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="children",
)
id: int = ormar.Integer(name="child_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
born_year: int = ormar.Integer(name="year_born", nullable=True)
class ArtistChildren(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="children_x_artists",
)
class Artist(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
tablename="artists",
)
id: int = ormar.Integer(name="artist_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
born_year: int = ormar.Integer(name="year")
children = ormar.ManyToMany(Child, through=ArtistChildren)
|
Remplacer le Query Set par défaut
Si vous souhaitez personnaliser les requêtes exécutées par ormar, vous pouvez définir votre propre classe d'ensemble de requêtes (avec une extension ormar QuerySet) dans la classe de modèle, qui est QuerySet par défaut.
Vous pouvez fournir une nouvelle classe comme argument queryset_class dans l'ormar_config de la classe.
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 | Importer à Ormar
depuis ormar.queryset.queryset import QuerySet
de fastapi import HTTPException
class MyQuerySetClass(QuerySet):
async def first_or_404(self, *args, **kwargs):
entity = await self.get_or_none(*args, **kwargs)
Si l'entité est None:
# in fastapi ou starlette
raise HTTPException(404)
Classe Book(modèle ormar):
ormar_config = base_ormar_config.copy(
queryset_class=MyQuerySetClass,
tablename="livre",
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=32)
#Quand le livre n'est pas trouvé, raise `404` dans votre vue.
book = await Book.objects.first_or_404(nom ="123")
|
Conseils sur le type
Veuillez noter que pour un meilleur support IDE et une vérification mypy, vous pouvez fournir des conseils de type.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Notez que l'indication de type est facultative, donc un code ormar pleinement valide peut ressembler à ceci:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id = ormar.Integer(primary_key=True)
name = ormar.String(max_length=100)
completed = ormar.Boolean(default=False)
|
!!!AVERTISSEMENT Même si vous utilisez des indices de type, ormar ne les utilisera pas pour construire des champs pydantiques!
| Les points de Type sont là uniquement pour soutenir les checkers statiques et l'intégration,
`ormar` construit des annotations utilisées par `pydantic` de ses propres champs.
|
Dépendance
Étant donné qu 'ormar repose sur une base de données et sqlalchemy-core pour la connexion à la base de données et la création de tables, vous devez attribuer deux paramètres spéciaux à chaque modèle.
Base de données
L'un est une instance de base de données créée avec une URL de base de données au format sqlalchemy connection string.
Les instances créées doivent être passées à chaque modèle en utilisant le paramètre de base de données objet ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!Conseil Vous n'avez qu'à créer une instance de base de données une seule fois et l'utiliser pour tous vos modèles. vous pouvez créer plusieurs bases de données si vous souhaitez en utiliser plusieurs.
Alchimie
La deuxième dépendance est l'instance sqlalchemy MetaData.
Les instances créées doivent être passées à chaque modèle en utilisant le paramètre de métadonnées d'objet ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!Conseil Vous n'avez besoin que de créer une instance MetaData une seule fois et de l'utiliser pour tous vos modèles. si vous souhaitez utiliser plusieurs bases de données, vous pouvez créer plusieurs bases de données.
Meilleures pratiques
Notez qu 'ormar nécessite un champ nommé ormar_config qui est une instance de la classe OrmarConfig. Pour simplifier la gestion de la configuration, la classe OrmarConfig fournit une méthode de réplication. par conséquent, au lieu de donner les mêmes paramètres à tous les modèles encore et encore, vous devez créer un objet sous-jacent et utiliser sa copie.
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 | from typing import Optional
import databases
import ormar
import sqlalchemy
DATABASE_URL = "sqlite:///test.db"
ormar_base_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL),
metadata=sqlalchemy.MetaData(),
)
class Artist(ormar.Model):
# note that tablename is optional
# if not provided ormar will user class.__name__.lower()+'s'
# -> artists in this example
ormar_config = ormar_base_config.copy()
id: int = ormar.Integer(primary_key=True)
first_name: str = ormar.String(max_length=100)
last_name: str = ormar.String(max_length=100)
born_year: int = ormar.Integer(name="year")
class Album(ormar.Model):
ormar_config = ormar_base_config.copy()
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
artist: Optional[Artist] = ormar.ForeignKey(Artist)
|
Le nom de la table
Par défaut, les noms de table sont créés à partir des noms de classe de modèle, c'est-à-dire des noms minuscules avec un "s".
Vous pouvez remplacer ce paramètre en fournissant un paramètre de nom de table pour l'objet ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
# if you omit this parameter it will be created automatically
# as class.__name__.lower()+'s' -> "courses" in this example
tablename="my_courses",
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Contraintes
Au niveau du modèle, vous pouvez également définir des contraintes en termes de modèle sur les colonnes sql.
Actuellement, seules les contraintes IndexColumns, UniqueColumns et CheckColumns sont prises en charge.
Note!!!Notez que vous ne devez utiliser les deux contraintes que si vous souhaitez définir un nom sur une contrainte ou si vous souhaitez définir un index sur plusieurs colonnes, sinon préférez l'index et les attributs uniques sur le champ ormar.
!!!Tip Pour en savoir plus sur les contraintes de colonne telles que les clés primaires, uniques, étrangères, etc., visitez Champs.
Colonne unique
Vous pouvez définir ce paramètre en fournissant le paramètre de contrainte d'objet ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
# define your constraints in OrmarConfig of the model
# it's a list that can contain multiple constraints
# hera a combination of name and column will have to be unique in db
constraints=[ormar.UniqueColumns("name", "completed")],
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Note!!!Notez que les contraintes sont pour des combinaisons de colonnes qui devraient être uniques. pour rendre une colonne unique, utilisez un paramètre universel unique. bien sûr, vous pouvez utiliser ce paramètre pour rendre de nombreuses colonnes uniques, mais chaque colonne sera vérifiée séparément.
Index des colonnes
Vous pouvez définir ce paramètre en fournissant le paramètre de contrainte d'objet ormar_config.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
# define your constraints in OrmarConfig of the model
# it's a list that can contain multiple constraints
# hera a combination of name and column will have a compound index in the db
constraints=[ormar.IndexColumns("name", "completed")],
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
!!!note Notez que les contraintes sont pour la combinaison des colonnes qui doivent être incluses dans l'index. pour définir un index de colonne, utilisez un paramètre public unique. bien sûr, vous pouvez utiliser ce paramètre pour définir de nombreuses colonnes comme index, mais chaque colonne sera un index distinct.
Vérifier les colonnes
Vous pouvez définir ce paramètre en fournissant le paramètre de contrainte d'objet ormar_config.
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 | import datetime
import databases
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
# define your constraints in OrmarConfig of the model
# it's a list that can contain multiple constraints
# hera a combination of name and column will have a level check in the db
constraints=[
ormar.CheckColumns("start_time < end_time", name="date_check"),
],
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
start_date: datetime.date = ormar.Date()
end_date: datetime.date = ormar.Date()
|
!!!Notez que certaines bases de données ne supportent pas activement les contraintes de vérification (par exemple MySQL).
Structure cantilever
Étant donné que chaque modèle ormar.Model est également un modèle pydantique, vous devrez peut-être ajuster les paramètres de votre configuration pydantique.
La façon de le faire dans pydantic est d'ajuster les paramètres du dictionnaire model_config fourni au modèle, qui fonctionne exactement de la même manière pour le modèle ormar.
Ainsi, pour définir vos propres préférences, vous devez fournir au modèle non seulement la classe ormar_config, mais aussi la classe model_config = ConfigDict().
!!!Note Pour en savoir plus sur les paramètres disponibles, visitez la page de configuration de pydantic.
Notez que si vous ne fournissez pas votre propre configuration, ormar le fera pour vous. la configuration par défaut fournie est la suivante:
| model_config = ConfigDict(validate_assignment=True, ser_json_octets ="base64")
|
Donc, pour remplacer les paramètres ou fournir votre propre modèle d'exemple, voici comment:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | import databases
import ormar
import pydantic
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Course(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=database,
metadata=metadata,
)
model_config = pydantic.ConfigDict(frozen=True)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
|
Champs supplémentaires dans le modèle
Par défaut, ormar vous empêche de passer des champs supplémentaires à un modèle.
Si vous essayez de le faire, une erreur de modélisation sera levée.
Étant donné que les champs supplémentaires ne peuvent pas être enregistrés dans la base de données, l'interdiction par défaut de ces champs semble être une option viable.
Au lieu de cela, dans pydantic, l'option par défaut est d'ignorer ces champs supplémentaires, donc ormar fournit le paramètre ormar_config.extra pour fonctionner de la même manière.
Pour ignorer les champs supplémentaires passés à ormar, définissez ce paramètre sur Extra.ignore au lieu de Extra.forbid par défaut.
Veuillez noter que les champs supplémentaires ne sont pas autorisés à être acceptés par ormar, vous pouvez seulement les ignorer ou les interdire (en levant une exception si elle existe).
| d'ormar import Extra, OrmarConfig
classe enfant (modèle ormar):
ormar_config = OrmarConfig(
tablename="enfants"
extra=Extra.ignore # set extra setting to prevent exceptions on extra fields presence
)
id: int = ormar.Integer(nom ="child_id", primary_key=True)
first_name: str = ormar.String(name="fname", max_length=100)
last_name: str = ormar.String(name="lname", max_length=100)
|
Pour définir les mêmes paramètres sur tous les modèles, consultez les meilleures pratiques et le concept base_ormar_config.
Type de modèle
Par défaut, lorsqu 'une base de données est interrogée avec un modèle donné, les modèles sont triés par ordre croissant de colonne Primary_key. Si vous souhaitez modifier le comportement par défaut, vous pouvez le faire en fournissant le paramètre orders_by au modèle ou à l'objet mar_config.
Exemple de tri par défaut (non spécifié-donc spécifié par la clé primaire):
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | base_ormar_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL),
metadata=sqlalchemy.MetaData(),
)
# default sort par colonne id ascending
Auteur de classe (modèle ormar):
ormar_config = base_ormar_config.copy(
tablename="auteurs",
)
id: int = ormar.Integer(primary_key=True)
nom: str = ormar.String(max_length=100)
|
modifiée par
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | base_ormar_config = ormar.ormarConfig(
database=databases.Database(DATABASE_URL),
metadata=sqlalchemy.MetaData(),
)
# now default sort par nom descendant
Auteur de classe (modèle ormar):
ormar_config = base_ormar_config.copy(
orders_by = ["-name"],
tablename="auteurs",
)
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
|
Initialisation du modèle
Il existe deux façons de créer et d'enregistrer des instances de modèle dans une base de données.
Si vous prévoyez de modifier l'instance plus tard lors de l'exécution du programme, vous pouvez lancer le modèle en tant que classe normale et attendre l'appel de save().
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 | import asyncio
import databases
import ormar
import sqlalchemy
from examples import create_drop_database
DATABASE_URL = "sqlite:///test.db"
ormar_base_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL), metadata=sqlalchemy.MetaData()
)
class Course(ormar.Model):
ormar_config = ormar_base_config.copy(tablename="courses")
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
@create_drop_database(base_config=ormar_base_config)
async def run_query():
course = Course(name="Painting for dummies", completed=False)
await course.save()
await Course.objects.create(name="Painting for dummies", completed=False)
asyncio.run(run_query())
|
Si vous souhaitez lancer le modèle et l'enregistrer dans la base de données en même temps, utilisez la méthode create() de QuerySet.
Pour créer plusieurs objets à la fois, vous pouvez utiliser la méthode bulk_create() QuerySet.
Chaque modèle possède un ensemble de requêtes initialisées en tant que paramètres objet.
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 | import asyncio
import databases
import ormar
import sqlalchemy
from examples import create_drop_database
DATABASE_URL = "sqlite:///test.db"
ormar_base_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL), metadata=sqlalchemy.MetaData()
)
class Course(ormar.Model):
ormar_config = ormar_base_config.copy(tablename="courses")
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
completed: bool = ormar.Boolean(default=False)
@create_drop_database(base_config=ormar_base_config)
async def run_query():
course = Course(name="Painting for dummies", completed=False)
await course.save()
await Course.objects.create(name="Painting for dummies", completed=False)
asyncio.run(run_query())
|
!!!info Pour en savoir plus sur les ensembles de requêtes, y compris les opérations par lots, et les méthodes disponibles, visitez Requêtes
État de conservation du modèle
Chaque instance du modèle est un objet python distinct, qui ne connaît rien les uns des autres.
| track1 = await Track.objects.get(nom ='The Bird')
track2 = await Track.objects.get(nom ='The Bird')
assert track1 == track2 # True
track1.name ="Bird2"
await track1.save ()
assert track1.name == track2.name # False
# track2 ne doit pas être mis à jour et ne sait rien sur track1
|
L'objet lui-même a un état de sauvegarde qui est défini comme suit:
- Sauvegarder le modèle après avoir enregistré/mis à jour/chargé/mis à jour la méthode d'insertion sur le modèle
- après sauvegarde du modèle
create/get/first/all/get_or_create/update_or_create
- Le modèle est sauvegardé lorsqu 'il est passé à bulk_update et bulk_create
- Enregistrer le modèle après avoir ajouté/supprimé des objets liés à ManyToMany (enregistrement/suppression automatique via une instance de modèle)
- Le modèle n'est pas enregistré après avoir modifié l'un de ses propres champs (y compris pk comme alias de Model.pk)
- Le modèle n'est pas sauvegardé après l'ajout/suppression d'objets liés à ForeignKey (colonne fk non sauvegardée)
- ne sauvegarde pas le modèle après instanciation avec__init__(sans QuerySet.create ou avant l'appel à save)
Vous pouvez vérifier si le modèle a été sauvegardé avec la propriété ModelInstance.saved