Knex: Comment changer la contrainte nullable dans la colonne à l'intérieur d'une migration ?

Créé le 22 févr. 2016  ·  10Commentaires  ·  Source: knex/knex

J'essaie de modifier une contrainte sur une colonne mais cela semble juste essayer de recréer la colonne et échoue.

exports.up = function(knex, Promise) {  
  return knex.schema.table("images", function(table) {
    table.string("checksum").notNullable();
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.table("images", function(table) {
    table.string("checksum").nullable();
  });
};
PR please feature request schema

Commentaire le plus utile

Pour ceux d'entre vous qui viennent de google, la syntaxe est la suivante :

Conversion d'une colonne nonNullable existante pour qu'elle soit Nullable (inversez le haut/bas si vous voulez qu'un nonNullable soit Nullable).

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};

Tous les 10 commentaires

@Rush Je ne pense vraiment pas que .nullable() et .notNullable() soient destinés à être utilisés pour cela. Il me semble que vous voulez exécuter quelque chose comme

ALTER TABLE tableName ALTER COLUMN columnName DROP NOT NULL
ALTER TABLE tableName ALTER COLUMN columnName SET NOT NULL

Et actuellement, je ne trouve rien dans l'API à part .raw qui pourrait gérer cela.

@rhys-vdw Quelle est votre opinion à ce sujet ? .dropNotNull() / .setNotNull() ou similaire pourrait-il être un ajout digne de schemaBuilder ? Ce serait très similaire à l'implémentation de .dropForeign() .

.dropNotNull()/.setNotNull() ou similaire pourrait-il être un ajout digne de schemaBuilder ?

Oui, mais probablement comme .dropNullable(...columnNames) et .setNullable(...columnNames) .

@rhys-vdw À la réflexion, j'ai l'impression que ce sera trop gênant pour tout dialecte autre que postgres. Personnellement, je ne vois pas de bonne solution aux problèmes suivants :

Postgres dropNullable: ALTER TABLE table ALTER COLUMN columnName DROP NOT NULL
Postgres setNullable: ALTER TABLE table ALTER COLUMN columnName SET NOT NULL

MSSQL dropNullable: ALTER TABLE table ALTER COLUMN columnName columnType NULL
MSSQL setNullable: ALTER TABLE table ALTER COLUMN columnName columnType NOT NULL

MySQL/Maria/Oracle dropNullable: ALTER TABLE table MODIFY columnName columnType NULL;
MySQL/Maria/Oracle setNullable: ALTER TABLE table MODIFY columnName columnType NOT NULL;

Sqlite: No support?

Cela entraînerait des arguments incohérents basés sur le dialecte que vous utilisez. Postgres ne veut que le nom, tandis que d'autres veulent le nom + le type de données (+ valeur par défaut ?).

Qu'en pensez-vous, cela vaut-il la peine?

Nous avions l'habitude de prendre en charge à la fois SQLite et Postgres, mais SQLite est si différent qu'aucune quantité d'abstraction ne peut le cacher ... donc lancer une exception est probablement la bonne chose dans de tels cas. Les migrations ActiveRecord de Rails prennent en charge l'évolution des contraintes, alors c'est peut-être l'endroit pour s'inspirer ?

Cela était possible à mettre en œuvre après tout. J'ai fait un PR.

+1 -- Je viens de rencontrer ce problème aussi, et c'est en quelque sorte un bloqueur. Chaque fois que vous devez effectuer une migration qui mappe des représentations pour des colonnes non nullables, vous en aurez besoin.

@morungos n'est pas vraiment un bloqueur, car vous pouvez toujours passer à knex.raw pour des choses qui pour knex n'ont pas d'API spécialisées (beaucoup de choses lors de l'écriture de migrations).

Si cette pull request est terminée, ce problème peut également être fermé https://github.com/tgriesser/knex/pull/1759

Oui, j'ai utilisé .raw plusieurs fois, mais si cela se transforme en déclarations entières, cela commence à remettre en question l'utilisation complète des migrations du genou. En fin de compte, j'ai utilisé une solution de contournement : il suffit d'utiliser par défaut une valeur étrange non nulle, puis d'appliquer des règles de mappage pour mettre à jour les valeurs, puis de supprimer l'original. Mais cela peut devenir difficile à faire si vous appliquez l'intégrité, en particulier avec MySQL et c'est la mauvaise habitude d'exiger l'intégrité même pendant les étapes intermédiaires.

Pour ceux d'entre vous qui viennent de google, la syntaxe est la suivante :

Conversion d'une colonne nonNullable existante pour qu'elle soit Nullable (inversez le haut/bas si vous voulez qu'un nonNullable soit Nullable).

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};

Juste pour info, au cas où vous essayez de changer nullable en nonNullable vous devez d'abord remplir cette colonne avec quelque chose, sinon vous obtiendrez une erreur.

Pour ceux d'entre vous qui viennent de google, la syntaxe est la suivante :

Conversion d'une colonne nonNullable existante pour qu'elle soit Nullable (inversez le haut/bas si vous voulez qu'un nonNullable soit Nullable).

exports.up = knex => {
  return knex.schema
    .alterTable('images', (table) => {
      table.string('checksum').nullable().alter();
    });
};

exports.down = knex => {
  return knex.schema
    .alterTable('images', table => {
      table.string('checksum').notNullable().alter();
    });
};
Cette page vous a été utile?
0 / 5 - 0 notes