Développement #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.
Files
Associated revisions
misc: add missed migrations (#42312)
misc: add migration to ensure jsonb type (#42312)
History
Updated by Valentin Deniaud over 4 years ago
À 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.
Updated by Frédéric Péters over 4 years ago
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
Updated by Valentin Deniaud over 4 years ago
OK, je comprends pas le pourquoi du comment, peut-être que Benj en saura plus.
Updated by Lauréline Guérin over 4 years ago
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 :)
Updated by Valentin Deniaud over 4 years ago
- File 0001-misc-use-postgres-JSONField-41992.patch 0001-misc-use-postgres-JSONField-41992.patch added
- Tracker changed from Support to Développement
- Status changed from Nouveau to Solution proposée
- Patch proposed changed from No to Yes
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à.
Updated by Frédéric Péters over 4 years ago
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
Updated by Valentin Deniaud over 4 years ago
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 ?
Updated by Frédéric Péters over 4 years ago
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'), ]
Updated by Valentin Deniaud over 4 years ago
- File 0002-misc-add-missed-migrations-42312.patch 0002-misc-add-missed-migrations-42312.patch added
- File 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch added
- File 0001-misc-use-postgres-JSONField-42312.patch 0001-misc-use-postgres-JSONField-42312.patch added
Voilà pour la migration partout. Il faut que j'ajoute un test ?
Updated by Frédéric Péters over 4 years ago
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)
Updated by Valentin Deniaud over 4 years ago
- File 0002-misc-add-missed-migrations-42312.patch 0002-misc-add-missed-migrations-42312.patch added
- File 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch added
- File 0001-misc-use-postgres-JSONField-42312.patch 0001-misc-use-postgres-JSONField-42312.patch added
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.
Updated by Frédéric Péters over 4 years ago
reversible = False
Je mettrais True, et un backwards qui ne fait rien vu que ça vivait déjà très bien en jsonb; non ?
Updated by Valentin Deniaud over 4 years ago
- File 0002-misc-add-missed-migrations-42312.patch 0002-misc-add-missed-migrations-42312.patch added
- File 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch 0003-misc-add-migration-to-ensure-jsonb-type-42312.patch added
- File 0001-misc-use-postgres-JSONField-42312.patch 0001-misc-use-postgres-JSONField-42312.patch added
Oui tout à fait.
Updated by Frédéric Péters over 4 years ago
- Status changed from Solution proposée to Solution validée
Updated by Valentin Deniaud over 4 years ago
- Status changed from Solution validée to 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)
Updated by Frédéric Péters over 4 years ago
- Status changed from Résolu (à déployer) to Solution déployée
misc: use postgres JSONField (#42312)