Alembic est un outil de migration pour sqlalchemy, un orm python. Il n'y a pas beaucoup d'articles en japonais et je ne me suis souvent pas rendu compte que je l'utilisais, alors je vais écrire le point.
Alembic:http://alembic.zzzcomputing.com/en/latest/
Lorsqu'il existe plusieurs fichiers de modèle, il est nécessaire de combiner les métadonnées de la classe Base. http://liuhongjiang.github.io/hexotech/2015/10/14/alembic-support-multiple-model-files/ La méthode décrite dans ce blog fonctionne. Dans mon cas, j'ai essayé d'utiliser l'importation dynamique.
env.py
import importlib
from sqlalchemy.schema import MetaData
target_models =[
'path.to.models',
'another.models'
]
def import_model_bases():
"""import all target models base metadatas."""
lst = list(map(
lambda x: importlib.import_module(x).Base.metadata,
target_models
))
return lst
def combine_metadata(lst):
m = MetaData()
for metadata in lst:
for t in metadata.tables.values():
t.tometadata(m)
return m
target_metadata = combine_metadata(import_model_bases())
Si vous conservez le même nom de colonne, il ne détectera pas le changement de type. Il semble que cela soit défini par défaut. http://stackoverflow.com/questions/17174636/can-alembic-autogenerate-column-alterations Ceci est également modifié comme dans cet article.
env.py
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=True #ajouter à
)
with context.begin_transaction():
context.run_migrations()
Maintenant que vous êtes conscient du changement de type, vous rencontrez des problèmes avec le type booléen. Boolean est défini par tinyint dans mysql, mais lors de la comparaison, il est jugé que le type est différent et il essaie de supprimer et de créer des colonnes à chaque fois. De plus, même si je change le type de tinyint à integer, il ne peut pas être détecté correctement.
Si vous le corrigez avec le sentiment qu'il est écrit en référence à ici, cela fonctionnera. J'ai essayé comme suit.
env.py
#ajouter à
from sqlalchemy import engine_from_config, types
from sqlalchemy.dialects import mysql
def my_compare_type(context, inspected_column,
metadata_column, inspected_type, metadata_type):
"""my compser type for mysql."""
if isinstance(inspected_type, mysql.TINYINT) and\
isinstance(metadata_type, types.Boolean):
return False
if isinstance(inspected_type, mysql.TINYINT) and\
isinstance(metadata_type, types.Integer):
return True
return None
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=my_compare_type #Changement
)
with context.begin_transaction():
context.run_migrations()
Puisque l'alambic a de nombreuses fonctions et de nombreuses fonctions que je n'ai pas encore utilisées, j'ajouterai ce à quoi j'étais accro plus tard.
Recommended Posts