2012-02-28 4 views
1

Notre base de données ne définit actuellement aucune clé primaire sur les tables. Toutes les colonnes id sont simplement des index uniques. Je supprime ces index et les remplace par des clés primaires appropriées.Ajout de la clé primaire change le type de colonne

Mon problème: Dans Postgres 8.4.7, une table en particulier modifie le type de données de bigint à integer quand j'ajoute la clé primaire à la table.

J'ai la définition de tableau suivant:

psql=# \d events 
             Table "public.events" 
     Column   |   Type   |      Modifiers      
-----------------------+--------------------------+----------------------------------------------------- 
id     | bigint     | not null default nextval('events_id_seq'::regclass) 
[more columns omitted] 

Indexes: 
    "events_id_unique_pk" UNIQUE, btree (id) 
Foreign-key constraints: 
    "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id) 
    "events_event_configs_id_fk" FOREIGN KEY (event_config_id) REFERENCES event_configs(id) 
    "events_pdu_circuitbreaker_id_fk" FOREIGN KEY (pdu_circuitbreaker_id) REFERENCES pdu_circuitbreaker(id) 
    "events_pdu_id_fk" FOREIGN KEY (pdu_id) REFERENCES pdus(id) ON DELETE CASCADE 
    "events_pdu_outlet_id_fk" FOREIGN KEY (pdu_outlet_id) REFERENCES pdu_outlet(id) 
    "events_sensor_id_fk" FOREIGN KEY (sensor_id) REFERENCES sensors(id) 
    "events_user_id_fk" FOREIGN KEY (clearing_user_id) REFERENCES users(id) 
Referenced by: 
    TABLE "events" CONSTRAINT "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id) 
    TABLE "event_params" CONSTRAINT "events_params_event_id_fk" FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE 
Triggers: 
    event_validate BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE PROCEDURE event_validate() 

Voici ce qui se passe:

psql=# ALTER TABLE events ADD PRIMARY KEY (id); 
NOTICE: ALTER TABLE/ADD PRIMARY KEY will create implicit index "events_pkey" for table "events" 
ALTER TABLE 
psql=# \d events 
             Table "public.events" 
     Column   |   Type   |      Modifiers      
-----------------------+--------------------------+----------------------------------------------------- 
id     | integer     | not null default nextval('events_id_seq'::regclass) 
[more columns omitted] 

Indexes: 
    "events_pkey" PRIMARY KEY, btree (id) 
    "events_id_unique_pk" UNIQUE, btree (id) 
Foreign-key constraints: 
    "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id) 
    "events_event_configs_id_fk" FOREIGN KEY (event_config_id) REFERENCES event_configs(id) 
    "events_pdu_circuitbreaker_id_fk" FOREIGN KEY (pdu_circuitbreaker_id) REFERENCES pdu_circuitbreaker(id) 
    "events_pdu_id_fk" FOREIGN KEY (pdu_id) REFERENCES pdus(id) ON DELETE CASCADE 
    "events_pdu_outlet_id_fk" FOREIGN KEY (pdu_outlet_id) REFERENCES pdu_outlet(id) 
    "events_sensor_id_fk" FOREIGN KEY (sensor_id) REFERENCES sensors(id) 
    "events_user_id_fk" FOREIGN KEY (clearing_user_id) REFERENCES users(id) 
Referenced by: 
    TABLE "events" CONSTRAINT "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id) 
    TABLE "event_params" CONSTRAINT "events_params_event_id_fk" FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE 
Triggers: 
    event_validate BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE PROCEDURE event_validate() 

Je considère quelques solutions de contournement, mais je préfèrerais ne sais pas pourquoi ça se passe. Il y a quelques autres tables qui utilisent aussi bigint, donc je ne veux pas juste pirater une solution en place.

Ceci est scripté avec Liquibase, mais cela se passe aussi directement dans la console Postgres.


Mise à jour

Deux autres points:

  • Je peux créer une table simple avec un identifiant bigint et un index unique sur id, ajoutez la clé primaire, et le type de colonne reste le même.
  • Toutes les tables sont vides lors de l'exécution.

Cela pourrait-il avoir quelque chose à voir avec les contraintes?

+1

J'ai du mal à croire que l'ajout d'une contrainte de clé primaire puisse changer le type d'une colonne, mais supposons que pendant un certain temps c'est un bug. Mettez à jour vers la dernière version mineure et testez à nouveau. –

+0

@ MilenA.Radev C'est la sortie littérale de la console, et ces trois commandes ont été entrées séquentiellement. Nous sommes en train de passer de Postgres 8.4 à 9.1 de toute façon. Je peux tester contre cela dans quelques jours. – Brandan

Répondre

1

Je n'ai pas été capable de le reproduire le jour suivant, même après l'avoir reproduit plusieurs fois avec des témoins la première fois qu'il s'est produit. Je le fais craquer aux gremlins.

1

C'est assez intéressant. Je ne peux pas le reproduire avec la version 9.1.0 (oui, je devrais mettre à jour aussi!). Mais je ne sais pas exactement comment le tableau et la séquence d'origine ont été créés.

Cette page semble faire allusion à un changement automatique similaire de types entre SERIAL et ENTIER: http://grover.open2space.com/content/migrate-data-postgresql-and-maintain-existing-primary-key

Pourrait-il être quelque chose comme la création de la table à l'aide de série au lieu bigserial, puis forcer le type à BIGINT? Quelque chose entre la séquence et les manipulations de la clé primaire aurait pu le réinitialiser.

Questions connexes