Ici, nous résumons la méthode de définition d'une table à l'aide de SQLAlchemy. ** Ci-après, le dialecte (type DB) est mysql. ** **
Il peut être spécifié par mysql_charset
de __table_args__
.
Par exemple, si vous souhaitez spécifier charset comme utf8mb4
class User(Base):
__table_args__=({"mysql_charset": "utf8mb4"})
Et c'est suffisant. En passant, si vous spécifiez utf8, un avertissement sera émis comme suit.
Warning: (3719, "'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.")
ROW_FORMAT=DYNAMIC La longueur maximale de la clé de l'index est de 3072 octets, mais si la version mysql est 5.6 ou antérieure, la valeur par défaut est de 767 octets. Par conséquent, si vous utilisez la version 5.6 ou antérieure et écrivez comme ci-dessous, une erreur se produira.
class User(Base):
__table_args__=({"mysql_charset": "utf8mb4"})
a=Column(String(255), unique=True)
Cela est dû au fait que utf8mb4 est spécifié, donc 255 * 4 = 1020 (octet), ce qui dépasse 767 octets.
(À propos, dans le cas de utf8mb3, 255 * 3 = 765 (octet) est correct)
Par conséquent, en définissant ROW_FORMAT = DYNAMIC
, la longueur de clé maximale de l'index devient 3072 octets.
Vous pouvez écrire comme suit.
class User(Base):
__table_args__=({"mysql_charset": "utf8mb4", "mysql_row_format": "DYNAMIC"})
a=Column(String(255), unique=True)
Dans 5.7 et versions ultérieures, par défaut, ROW_FORMAT = DYNAMIC
.
Il peut être spécifié par mysql_engine
de __table_args__
.
Par exemple, si vous souhaitez spécifier le moteur DB pour InnoDB,
class User(Base):
__table_args__=({"mysql_engine": "InnoDB"})
Et c'est suffisant.
Data Types
En tant que types génériques de SQLAlchemy, vous pouvez l'importer et l'utiliser avec from sqlalchemy.types import hogehoge
.
Par exemple, il y a les suivants.
from sqlalchemy.types import Float
from sqlalchemy.types import Integer
from sqlalchemy.types import String
from sqlalchemy.types import DateTime
Pour ces types génériques, SQL Alchemy sélectionnera les types de données appropriés en fonction du type de base de données à utiliser lorsque CREATE TABLE
.
Documents officiels (types génériques)
Cependant, par exemple, unsigned int, tiny int et timestamp type ne sont pas inclus dans les types génériques. Dans ce cas, utilisez from sqlalchemy.dialects.mysql import fugafuga
.
from sqlalchemy.dialects.mysql import INTEGER as Integer
from sqlalchemy.dialects.mysql import TINYINT as Tinyint
from sqlalchemy.dialects.mysql import TIMESTAMP as Timestamp
class User(Base):
a=Column(Integer(unsigned=True)) #a est un entier non signé
b=Column(Tinyint(1)) #b est minuscule int(1)
c=Column(Timestamp) #c est horodatage
(Documentation officielle (types de données MySQL))
Primary Key
Vous pouvez définir primary_key = True
dans la colonne.
class User(Base):
id=Column(Integer, primary_key=True) #id est la clé primaire
Si vous voulez créer une clé primaire composée, définissez primary_key = True
pour les deux.
class User(Base):
# id_1 et id_2 est une clé primaire composite
id_1=Column(Integer, primary_key=True)
id_2=Column(Integer, primary_key=True)
Auto Increment Définissez ʻautoincrement = True` dans la colonne.
class User(Base):
id=Column(Integer, autoincrement=True) #id est l'incrémentation automatique
Définissez server_default = hogehoge
dans la colonne.
Notez que vous devez passer string ou text () à server_default.
from sqlalchemy.dialects.mysql import TINYINT as Tinyint
class User(Base):
bool=Column(Tinyint(1), server_default="1") #Passing string
Si celui qui est passé est une chaîne, il se transforme en guillemets simples, et s'il s'agit de texte (), il change sans guillemets.
x=Column(String, server_default="val")
x STRING DEFAULT 'val' #Changer en guillemets simples
y=Column(DateTime, server_default=text("NOW()")
y DATETIME DEFAULT NOW() #Pas de devis
Documentation officielle (server_default)
Si vous voulez que la valeur par défaut soit current_timestamp, définissez from sqlalchemy.sql.functions import current_timestamp
et server_default = current_timestamp ()
.
from sqlalchemy.dialects.mysql import TIMESTAMP as Timestamp
from sqlalchemy.sql.functions import current_timestamp
class User(Base):
created_at=Column(Timestamp, server_default=current_timestamp())
Documentation officielle (current_timestamp) )
Il n'est pas reflété même si server_onupdate = hogehoge
est défini dans Column.
Par conséquent, si vous souhaitez définir DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
, utilisez server_default
.
from sqlalchemy.dialects.mysql import TIMESTAMP as Timestamp
from sqlalchemy.sql.expression import text
class User(Base):
created_at=Column(Timestamp, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
Et c'est suffisant. How to set DEFAULT ON UPDATE CURRENT_TIMESTAMP in mysql with sqlalchemy?
Vous pouvez définir nullable = False
dans la colonne.
class User(Base):
a=Column(Integer, nullable=False) #a est un entier et non nul
Si vous souhaitez mettre une contrainte Unique sur une seule colonne, vous pouvez définir ʻunique = True` dans Column.
class User(Base):
a=Column(Integer, unique=True) #a est int et unique
Si vous voulez mettre des contraintes uniques sur plusieurs colonnes, vous devez écrire sqlalchemy.schema.UniqueConstraint
dans __table_args__
.
from sqlalchemy.schema import UniqueConstraint
class User(Base):
#(a, b)En unique
__table_args__=(UniqueConstraint("a", "b", name="uq_user_00"))
a=Column(Integer)
b=Column(Integer)
Bien sûr, vous pouvez utiliser sqlalchemy.schema.UniqueConstraint
même si vous souhaitez mettre une contrainte unique sur une seule colonne.
Dans Colonne, définissez sqlalchemy.schema.ForeignKey
.
Fondamentalement, sqlalchemy.schema.ForeignKey (" {nom_table}. {Nom_colonne} ", name =" {nom_constraint_clé_tranger} ")
from sqlalchemy.schema import ForeignKey
class User(Base):
__tablename__="users"
id=Column(Integer, nullable=False, autoincrement=True, primary_key=True)
name=Column(String(255), nullable=False)
class TestResult(Base):
__tablename__="test_results"
id=Column(Integer, nullable=False, autoincrement=True, primary_key=True)
value=Column(Integer, nullable=False)
user_id=Column(Integer, ForeignKey("users.id", name="fk_test_results_00", nullable=False)) #L'identifiant de la table des utilisateurs est ForeignKey
Si vous voulez définir OnUpdate ou OnDelete, ajoutez ʻonupdate = "CASCADE" ou ʻondelete =" CASCADE "
dans sqlalchemy.schema.ForeignKey ()
.
Document officiel (ForeignKey.params.column)
En guise de mise en garde, parmi les options à écrire dans Column, DataType et ForeignKey doivent être écrites avant, et celles passées avec "=" doivent être écrites après.
relation
En créant une relation, vous pouvez suivre la clé étrangère sans la rejoindre explicitement.
La relation peut être définie sur `hoge = sqlalchemy.orm.relationship (" {nom de classe} ", uselist = {True ou False}) ʻ comme dans la définition de colonne.
Uselist est défini sur True s'il existe plusieurs données liées pour une seule donnée et sur False s'il n'y en a qu'une.
Dans ce qui suit, User: TestResult = one: many.
from sqlalchemy.schema import ForeignKey
from sqlalchemy.orm import relationship
class User(Base):
__tablename__="users"
id=Column(Integer, nullable=False, autoincrement=True, primary_key=True)
name=Column(String(255), nullable=False)
test_result=relationship("TestResult", uselist=True) #Créer une relation entre User et TestResult,Plusieurs données à lier
class TestResult(Base):
__tablename__="test_results"
id=Column(Integer, nullable=False, autoincrement=True, primary_key=True)
value=Column(Integer, nullable=False)
user_id=Column(Integer, ForeignKey("users.id", name="fk_test_results_00", nullable=False)) #L'identifiant de la table des utilisateurs est ForeignKey
user=relationship("User") #Créer une relation entre TestResult et User,Une seule donnée à connecter
En définissant une relation comme celle-ci, vous pouvez appeler une instance de chaque classe comme suit.
test_result_1=session.query(TestResult).filter(TestResult.id==1).one() # test_Dans le tableau des résultats, récupérez celui avec l'ID 1.
user_of_test_result_1=test_result_1.user #test_result_1 utilisateur_Vous pouvez récupérer une instance de la classe User dont l'ID correspond à l'ID.
# user_of_test_result_1=User
user_1=session.query(User).filter(User.id==1).one() #Dans le tableau des utilisateurs, récupérez celui avec l'ID 1.
test_results_of_user_1=user_1.test_result # user_Identifiant utilisateur correspondant sur 1_Vous pouvez récupérer une liste d'instances de la classe TestResult avec id
# test_results_of_user_1=[TestResult, TestResult, ...]
L'une des options est paresseuse, et ce paramètre vous permet de définir le moment auquel la table à laquelle la relation est définie est lue. Par défaut, il est chargé lors de son appel.
Identique à la valeur par défaut. Il est lu lorsque la destination de la relation est appelée.
test_result_1=session.query(TestResult).filter(TestResult.id==1).one() #L'utilisateur n'est pas encore chargé ici.
user_of_test_result_1=test_result_1.user #L'utilisateur est chargé ici
lazy="immediate" Lorsque la source de la relation est appelée, la destination de la relation est également appelée. La requête est émise séparément pour appeler la source et la destination de la relation.
test_result_1=session.query(TestResult).filter(TestResult.id==1).one() #L'utilisateur est également chargé ici
Lorsque la source de la relation est appelée, la destination de la relation est également appelée. La différence avec lazy = "immédiat" est le nombre de fois où la requête est émise. Puisqu'elle est appelée par jointure, la requête ne peut être émise qu'une seule fois. Document officiel (relation)
Cet article a été rédigé en référence aux informations suivantes. ・ Document officiel
Recommended Posts