L'ajout d'une colonne non nullable à une table d'échec. Est l'attribut “value” d'être ignoré?
Contexte: nous avons un Graal 1.3.7 application et utilisez Liquibase pour gérer nos migrations de base de données.
Je suis en train d'ajouter une nouvelle colonne à une table existante qui n'est pas vide.
Mon révision ressemble à ceci:
changeSet(author: "someCoolGuy (generated)", id: "1326842592275-1") {
addColumn(tableName: "layer") {
column(name: "abstract_trimmed", type: "VARCHAR(455)", value: "No text") {
constraints(nullable: "false")
}
}
}
Qui devrait avoir inséré la valeur "Pas de texte" dans chaque ligne existante, et, par conséquent, satisfait la contrainte not null. Liquibase "Ajouter une Colonne" docs.
Mais quand les migrations des révisions sont appliquées-je obtenir de l'exception suivante:
liquibase.exception.DatabaseException: Error executing SQL ALTER TABLE layer ADD abstract_trimmed VARCHAR(455) NOT NULL: ERROR: column "abstract_trimmed" contains null values
Qui me ressemble, il n'est pas à l'aide de la "valeur" de l'attribut.
Si je change de révision de travailler ressembler à celui-ci, je peux réaliser la même chose. Mais je ne veux pas (et ne doit pas) faire.
changeSet(author: "someCoolGuy (generated)", id: "1326842592275-1") {
addColumn(tableName: "layer") {
column(name: "abstract_trimmed", type: "VARCHAR(455)")
}
addNotNullConstraint(tableName: "layer", columnName:"abstract_trimmed", defaultNullValue: "No text")
}
Est Liquibase vraiment ignorant mon value
attribut, ou est-il autre chose ici que je peux pas voir?
Je suis en utilisant Graal 1.3.7, Base de données-migration plugin 1.0, Postgresql 9.0
OriginalL'auteur David | 2012-01-18
Vous devez vous connecter pour publier un commentaire.
Réponse courte
L'attribut "value" ne fonctionnera pas si vous ajoutez un non-nulle contrainte au moment de la colonne de la création (ce qui n'est pas mentionné dans la la documentation). Le SQL généré ne sera pas en mesure d'exécuter.
Solution de contournement
La solution de contournement décrite dans la question, la façon d'aller. Le SQL qui en résulte sera:
Ajouter la colonne
Définie à une valeur non nulle pour chaque ligne
Ajouter la contrainte not NULL
Pourquoi?
Une colonne par défaut n'est insérée dans la colonne avec un
INSERT
. La "valeur" de la balise va le faire pour vous, mais après la colonne est ajoutée. Liquibase tente d'ajouter la colonne en une seule étape, avec laNOT NULL
contrainte en place:... qui est pas possible lorsque la table contient déjà des lignes. Il n'est tout simplement pas assez intelligent.
Solution de rechange
Depuis PostgreSQL 8.0 (donc presque toujours maintenant) une autre solution serait d'ajouter une nouvelle colonne avec une valeur non nulle
DEFAULT
clause:Le manuel sur
ALTER TABLE
:D'accord, le truc sur
text
/varchar
était un aparté.Je veux juste mentionner que la condition de la question de la solution fonctionne pour MySQL, tout n'est pas pour MS SQL et, comme il est facilement compréhensible à partir de la question - Postgres.
OriginalL'auteur Erwin Brandstetter
Utiliser "defaultValue" au lieu de "valeur" pour définir une valeur par défaut pour la nouvelle colonne.
OriginalL'auteur Nogge