La modification d'un Enum champ à l'aide d'un Alambic
Comment puis-je ajouter un élément à un champ Enum dans un alambic de la migration lors de l'utilisation d'une version de PostgreSQL âgés de plus de 9.1 (ce qui ajoute de l'ALTER TYPE pour les enums)? Cette DONC, la question, explique le direct, mais je ne suis pas tout à fait sûr de la meilleure façon de le traduire à l'aide de l'alambic.
C'est ce que j'ai:
new_type = sa.Enum('nonexistent_executable', 'output_limit_exceeded',
'signal', 'success', 'timed_out', name='status')
old_type = sa.Enum('nonexistent_executable', 'signal', 'success', 'timed_out',
name='status')
tcr = sa.sql.table('testcaseresult',
sa.Column('status', new_type, nullable=False))
def upgrade():
op.alter_column('testcaseresult', u'status', type_=new_type,
existing_type=old_type)
def downgrade():
op.execute(tcr.update().where(tcr.c.status==u'output_limit_exceeded')
.values(status='timed_out'))
op.alter_column('testcaseresult', u'status', type_=old_type,
existing_type=new_type)
Ci-dessus, malheureusement, ne produit ALTER TABLE testcaseresult ALTER COLUMN status TYPE status
lors de la mise à niveau, qui consiste essentiellement à ne rien.
Vous devez vous connecter pour publier un commentaire.
J'ai décidé d'essayer de suivre le postgres approche aussi directement que possible, et est venu avec la suite de la migration.
Il semble que l'alambic a pas de support direct pour les
USING
déclaration dans sonalter_table
méthode.ADD VALUE
a été autour depuis 9.1. Cependant, même dans la section 9.4, l'opération ne peut pas être fait à l'intérieur d'une transaction de bloc et tous alambic migrations se produisent dans les transactions.ADD VALUE
dans PostgreSQL 10 et autant que je sache aucun des plans à mettre en œuvre que dans la version 11.J'ai utilisé un peu plus simple avec moins d'étapes que l'on a accepté la réponse, que j'ai basé cette sur. Dans cet exemple, je vais faire semblant de l'enum en question est appelé "status_enum", parce que dans la accepté de répondre à l'utilisation de "statut" pour la colonne et enum qui me confond.
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column "category_type" does not exist
mon nom de colonne estcaterory_types' and enum name is
CATEGORY_TYPE` qui est un OrderedDict , j'utilise Postgres 10.4 et alambic 0.9.9De Postgres 9.1 l'ajout d'une nouvelle valeur à une enum peut être fait avec le
MODIFIER le TYPE
déclaration. Ceci est compliqué par le fait que il ne peut pas être fait dans une transaction. Cependant cela peut être contourné par commettre l'alambic de la transaction voir ici.J'ai effectivement eu des problèmes en utilisant l'ancienne, plus détaillé, solution parce que Postgres ne pouvait pas convertir automatiquement la valeur par défaut pour la colonne.
Cela fonctionne sans problèmes:
Référence
J'ai eu le même problème en essayant de migration d'un type de colonne à l'autre. J'utilise les conditions suivantes:
Vous pouvez fournir l'argument
postgresql_using
comme un kwarg dealembic.op.alter_column
.J'espère que cela peut aider.
postgresql_using="my_column::text::PostgesEquivalentOfNewType"
Dans le cas de cette question, il est en fait un must have. Cependant, cette réponse est génial, il m'a sauvé beaucoup de temps 🙂En droit SQL, ce serait travailler pour Postgres, si l'ordre des choses dans votre enum n'a pas besoin d'être exactement comme ci-dessus:
ALTER TYPE ... ADD VALUE ...
ne peut pas être utilisé à l'intérieur d'une transaction.downgrade
J'avais besoin de déplacer des données lors de la migration de types de, y compris la suppression de certains vieux types, alors j'ai pensé écrire une manière plus générale de faire cela en fonction sur le (génial) a accepté de répondre (https://stackoverflow.com/a/14845740/629272). Espérons que cela aide quelqu'un d'autre dans le même bateau!
Depuis que j'ai eu la conversion des erreurs et des problèmes avec les valeurs par défaut, j'ai écrit un même généralisée de la réponse repose sur le reconnus:
Cela peut être appelé à partir d'upgrade /downgrade en tant que tel:
Tous invalidé les valeurs seront mis à server_default.