Development #42312
Pouvoir utiliser le JSONField de postgres
0%
Description
Dans #42008, on se rend compte que ce n'est pas possible car django-jsonfield < 1.3 est buggé et empêche d'utiliser les deux en parallèle.
Les tests passent avec la dernière version de django-jsonfield, mais les paquets debian sont plutôt autour de la version 1.1.
Alternativement, virer la dépendance avec django-jsonfield et tout faire avec postgres.
Ça a été fait dans a2, #29193, mais il y avait volonté de supporter sqlite, donc sans cette contrainte peut-être qu'il y a plus simple que ce qui est dit dans le ticket.
Fichiers
Révisions associées
misc: add missed migrations (#42312)
misc: add migration to ensure jsonb type (#42312)
Historique
Mis à jour par Valentin Deniaud il y a presque 4 ans
À la suite du début des discussions dans #42008,
Frédéric Péters a écrit :
Il me semble qu'on ne fait vraiment rien de particulier, qu'il n'y aurait même pas besoin de migration (juste traffiquer une précédente pour faire croire qu'on a depuis toujours utiliser le jsonfield de django.contrib.postgres).
Il y a effectivement pas grand chose à faire, mais au moins un ALTER TABLE, pour changer le type de la colonne de json à jsonb.
Une manière de faire déjà un peu lourde est présentée ici https://tech.polyconseil.fr/migrating-from-json-to-jsonb.html.
Mis à jour par Frédéric Péters il y a presque 4 ans
Mais, c'est déjà jsonb : (j'ai regardé la prod, et chez moi) (?)
Table « passerelle_xxx.opengis_featurecache » Colonne | Type | Modificateurs ----------+-------------------------+----------------------------------------------------------------------- id | integer | non NULL Par défaut, nextval('opengis_featurecache_id_seq'::regclass) lat | double precision | non NULL lon | double precision | non NULL data | jsonb | non NULL query_id | integer | non NULL text | character varying(2048) | non NULL
Mis à jour par Valentin Deniaud il y a presque 4 ans
OK, je comprends pas le pourquoi du comment, peut-être que Benj en saura plus.
Mis à jour par Lauréline Guérin il y a presque 4 ans
dans django-jsonfield:
def db_type(self, connection):
if connection.vendor == 'postgresql':
# Only do jsonb if in pg 9.4+
if connection.pg_version >= 90400:
return 'jsonb'
return 'text'
Heureusement qu'on n'a pas du text en prod :)
Mis à jour par Valentin Deniaud il y a presque 4 ans
- Fichier 0001-misc-use-postgres-JSONField-41992.patch 0001-misc-use-postgres-JSONField-41992.patch ajouté
- Tracker changé de Support à Development
- Statut changé de Nouveau à Solution proposée
- Patch proposed changé de Non à Oui
Bien vu ! Donc la seule chose qui va casser, c'est quand on essaiera de créer un objet sans remplir le JSONField, parce que django-jsonfield posait dynamiquement un default=dict
. Il y a deux endroits qui ont été identifiés dans les tests et que j'ai corrigés, mais sûrement qu'il y en a d'autre.
Et bien sûr, si il existe une prod datant d'avant postgres 9.4 ça va exploser en mille morceau, mais peut-être que c'est imaginable de corriger à la main/faire tourner un script dans ces cas là.
Mis à jour par Frédéric Péters il y a presque 4 ans
Et bien sûr, si il existe une prod datant d'avant postgres 9.4 ça va exploser en mille morceau, mais peut-être que c'est imaginable de corriger à la main/faire tourner un script dans ces cas là.
On peut imaginer une migration qui assure que c'est déjà jsonb, qui fasse le changement sinon ? Parce que ça va arriver et c'est quand même bien plus facilement gérable partout si c'est géré via une migration.
Table « passerelle_vincennes_entrouvert_com.csvdatasource_csvdatasource » Colonne | Type | Modificateurs ------------------+------------------------+------------------------------ id | integer | non NULL Par défaut, ... title | character varying(50) | non NULL slug | character varying(50) | non NULL description | text | non NULL csv_file | character varying(100) | non NULL columns_keynames | character varying(256) | non NULL skip_header | boolean | non NULL _dialect_options | text | <----------------- sheet_name | character varying(150) | non NULL
Mis à jour par Valentin Deniaud il y a presque 4 ans
Frédéric Péters a écrit :
On peut imaginer une migration qui assure que c'est déjà jsonb, qui fasse le changement sinon ? Parce que ça va arriver et c'est quand même bien plus facilement gérable partout si c'est géré via une migration.
Oui donc on retombe tout à fait sur la méthode du billet de blog cité plus haut, sauf qu'on s'autorise de changer le code et la db en même temps.
Tu écris une migration donc pour être sûr que je ne me lance pas sur une fausse piste, on parle d'écrire à la mano une dizaine de fichiers de migrations, soit un par app qui utilise un jsonfield, à base de RunSQL ?
Mis à jour par Frédéric Péters il y a presque 4 ans
Tu écris une migration donc pour être sûr que je ne me lance pas sur une fausse piste, on parle d'écrire à la mano une dizaine de fichiers de migrations, soit un par app qui utilise un jsonfield, à base de RunSQL ?
Oui; en modérant le côté "une dizaine de fichiers", genre en créant notre propre classe de EnsureJsonbType(Operation), pour tout à fait réduire la duplication, genre ces migrations seraient juste :
operations = [ EnsureJsonbType(model_name='csvdatasource', field_name='_dialect_options'), ]
Mis à jour par Valentin Deniaud il y a presque 4 ans
- Fichier 0002-misc-add-missed-migrations-42312.patch 0002-misc-add-missed-migrations-42312.patch ajouté
- Fichier 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch ajouté
- Fichier 0001-misc-use-postgres-JSONField-42312.patch 0001-misc-use-postgres-JSONField-42312.patch ajouté
Voilà pour la migration partout. Il faut que j'ajoute un test ?
Mis à jour par Frédéric Péters il y a presque 4 ans
Si ça te semble possible, oui un test pour la migration de passerelle/utils/db.py
ce serait super, mais si c'est galère parce que ça oblige à sortir de l'ORM pour traffiquer la DB, on peut juste être très attentif en relisant...
(mais il faut ajouter l'entête de licence au fichier)
Mis à jour par Valentin Deniaud il y a presque 4 ans
- Fichier 0002-misc-add-missed-migrations-42312.patch 0002-misc-add-missed-migrations-42312.patch ajouté
- Fichier 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch ajouté
- Fichier 0001-misc-use-postgres-JSONField-42312.patch 0001-misc-use-postgres-JSONField-42312.patch ajouté
Voilà un test, c'était pas si horrible, juste un petit peu.
Pas besoin de tester toutes les migrations je pense, le migrate exécuté de toute façon par les tests garanti normalement l'absence de faute de frappe sur le nom des tables/colonnes.
Mis à jour par Frédéric Péters il y a presque 4 ans
reversible = False
Je mettrais True, et un backwards qui ne fait rien vu que ça vivait déjà très bien en jsonb; non ?
Mis à jour par Valentin Deniaud il y a presque 4 ans
- Fichier 0002-misc-add-missed-migrations-42312.patch 0002-misc-add-missed-migrations-42312.patch ajouté
- Fichier 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch ajouté
- Fichier 0001-misc-use-postgres-JSONField-42312.patch 0001-misc-use-postgres-JSONField-42312.patch ajouté
Oui tout à fait.
Mis à jour par Frédéric Péters il y a presque 4 ans
- Statut changé de Solution proposée à Solution validée
Mis à jour par Valentin Deniaud il y a presque 4 ans
- Statut changé de Solution validée à Résolu (à déployer)
commit 9ef993108b945a41d2f9d430c6820c6c90cae6b0 Author: Valentin Deniaud <vdeniaud@entrouvert.com> Date: Mon May 4 14:04:32 2020 +0200 misc: add migration to ensure jsonb type (#42312) commit 0c5cad2296914a9d2a4865accd391eed507fdb55 Author: Valentin Deniaud <vdeniaud@entrouvert.com> Date: Mon May 4 14:03:41 2020 +0200 misc: add missed migrations (#42312) commit 5e1c910fbfacb15dd37ea8f0192561dcc15054bc Author: Valentin Deniaud <vdeniaud@entrouvert.com> Date: Thu Apr 30 12:00:34 2020 +0200 misc: use postgres JSONField (#42312)
Mis à jour par Frédéric Péters il y a presque 4 ans
- Statut changé de Résolu (à déployer) à Solution déployée
misc: use postgres JSONField (#42312)