web-dev-qa-db-fra.com

Convertir Postgres TIMESTAMP en TIMESTAMPTZ

J'ai une base de données de séries chronologiques de taille décente (~ 50k lignes) fonctionnant sur Postgres, avec quelques autres données structurées (dans une autre instance de base de données) qui est beaucoup plus petite.

Bêtement, quand j'ai initialement conçu la chose, j'avais tous les champs comme TIMESTAMP WITHOUT TIME ZONE, et maintenant je le paie avec des bugs ennuyeux liés au fuseau horaire. Je veux que tout soit explicite, donc je veux convertir le champ en TIMESTAMP WITH TIME ZONE. Je me rends compte que cela ne stocke pas d'informations supplémentaires, et tous mes horodatages sont déjà en UTC, donc la migration devrait être triviale, mais je me demandais s'il y avait des complications ou des blocages de déclenchement potentiels qui s'avérer problématique (il s'agit d'une base de données de production avec des clients qui en dépendent)?

8
GTF

Faites attention à ce que le fuseau horaire correct (UTC dans votre cas) soit appliqué lors de la conversion. Si ce n'est pas explicite, le fuseau horaire de la session en cours est supposé - généralement pas UTC.

ALTER TABLE tbl ALTER ts_column TYPE timestamptz USING ts_column AT TIME ZONE 'UTC';

Vérifiez également la validité par défaut d'une colonne. Toute expression fonctionnant avec le type de données timestamp (comme LOCALTIMESTAMP ou now()::timestamp) est soumise au même problème. Changer:

ALTER TABLE tbl ALTER ts_column SET DEFAULT now(); -- or current_timestamp

De toute évidence, les instructions écrivant dans la table doivent également utiliser timestamptz maintenant - ou vous avez une autre instance du même problème avec la conversion automatique du type timestamp [without time zone].

Comme il s'agit d'une base de données de production, il est préférable de tout faire en une seule transaction pour éviter les conditions de concurrence - ou même une seule instruction:

ALTER TABLE tbl
  ALTER ts_column TYPE timestamptz USING ts_column AT TIME ZONE 'UTC'
, ALTER ts_column SET DEFAULT now();

Bases:

13