====== Définition de modèles et Relations ======
Un modèle est une classe Python qui représente les enregistrements d'une table.
from app import db
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
def __repr__(self):
return '' % self.name
from app import db
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
email = db.Column(db.String(200), unique=True)
def __repr__(self):
return '' % self.username
def hello(self):
print("Hello, my name is %s." % self.name)
Pour un champ de type **LONGTEXT** sous **MySQL/MariaDB** :
...
from sqlalchemy.dialects.mysql import LONGTEXT
...
class Article(db.Model):
....
contenu = db.Column(LONGTEXT)
...
==== Clé primaire ====
Une **clé primaire** est obligatoire pour chaque table, elle est généralement
appelée **id**.
==== Types de colonnes ====
^Nom ^ Type Python ^
^Integer |int |Regular integer, typically 32 bits |
^SmallInteger|int |Short-range integer, typically 16 bits |
^BigInteger |int or long |Unlimited precision integer |
^Float |float |Floating-point number |
^Numeric |decimal.Decimal |Fixed-point number |
^String |str |Variable-length string |
^Text |str |Variable-length string, optimized for large or unbounded length |
^Unicode |unicode |Variable-length Unicode string |
^UnicodeText |unicode |Variable-length Unicode string, optimized for large or unbounded length |
^Boolean |bool |Boolean value |
^Date |datetime.date |Date value |
^Time |datetime.time |Time value |
^DateTime |datetime.datetime |Date and time value |
^Interval |datetime.timedelta |Time interval |
^Enum |str |List of string values |
^PickleType |Any Python object |Automatic Pickle serialization |
^LargeBinary |str |Binary blob |
==== Options des colonnes ====
^primary_key |If set to True, the column is the table’s primary key. |
^unique |If set to True, do not allow duplicate values for this column. |
^index |If set to True, create an index for this column, so that queries are more efficient. |
^nullable |If set to True, allow empty values for this column. If set to False, the column will not allow null values. |
^default |Define a default value for the column. |
==== Exemples ====
import datetime
class Exemple(db.Model):
...
# Entiers
id = db.Column(db.Integer, primary_key=True)
n = db.Column(db.Integer)
...
# Décimaux
f1 = db.Column(db.Float, precision=2)
f2 = db.Column(db.Numeric, precision=2)
...
# Chaînes
s = db.Column(db.String(100))
t = db.Column(db.Text)
...
# Date et heures
d1 = db.Column(db.Date, default=datetime.date.today)
d2 = db.Column(db.DateTime, default=datetime.datetime.now)
...
===== Relations =====
==== One-to-many ====
**One** Role <=> **Many** Users :
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(200))
# ...
users = db.relationship('User', backref='role')
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(200))
# ...
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
* Dans le modèle **User** : ''roles.id'' identifie la colonne ''id'' de la table ''roles'' comme
"clé étrangère" dans la relation.
* Dans le modèle **Role** : ''backref'' ajoute un attribut ''role'' au modèle **User**.
>>> r = Role(nom='Manager')
>>> u = User(nom='Marc', role=r)
>>> u.nom
'Marc'
>>> u.role.nom
'Manager'
==== Many-to-many ====
Voir [[https://stackoverflow.com/questions/19598578/how-do-primaryjoin-and-secondaryjoin-work-for-many-to-many-relationship-in-s]]
===== Création/mise à jour de la DB =====
Après avoir créé/modifié les modèles, il faut appliquer les changements
dans la base de données (ajout de tables, création de champs, etc.)
Ne rien faire manuellement, mais utiliser les
[[python:flask:flask_migrate|Migrations]].