browniebroke / django-codemod

A tool to automatically fix Django deprecations.

Home Page:https://django-codemod.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

django.contrib.postgres.fields.jsonb not captured by codemod

campbellmc opened this issue · comments

Link to Django docs
Link to release note section where the change and suitable replacement is mentioned:

https://docs.djangoproject.com/en/dev/releases/3.1/#postgresql-jsonfield

Quote of the relevant paragraph

In case links gets outdated/removed:

PostgreSQL JSONField¶
django.contrib.postgres.fields.JSONField and django.contrib.postgres.forms.JSONField are deprecated in favor of models.JSONField and forms.JSONField.

The undocumented django.contrib.postgres.fields.jsonb.KeyTransform and django.contrib.postgres.fields.jsonb.KeyTextTransform are also deprecated in favor of the transforms in django.db.models.fields.json.

The new JSONFields, KeyTransform, and KeyTextTransform can be used on all supported database backends.

Deprecation timeline

  • Deprecated in: 3.1
  • Removed in: 4.0

My thought is that this scenario should be covered by djcodemod although the case is not explicitly covered in the release notes for 3.1.

It shows up as a deprecation when doing checks but djcodemod doesn't fix:

mint_develop_django | pool.Pool.properties: (fields.W904) django.contrib.postgres.fields.JSONField is deprecated. Support for it (except in historical migrations) will be removed in Django 4.0.
mint_develop_django |   HINT: Use django.db.models.JSONField instead.

The offending import in models.py is:

from django.contrib.postgres.fields.jsonb import JSONField

Probably an artifact of the way Pycharm offers imports.

If you're talking more about the undocumented deprecated transforms, I think django-codemod doesn't handle them at the moment, I don't have any objections in adding them: they are mentioned in the release notes, which I think makes them candidate for inclusion. Pull request welcome.

If you're talking about JSONField, that should be already covered by JSONModelFieldTransformer:

class JSONModelFieldTransformer(BaseFuncRenameTransformer):
"""Replace postgres' JSON field with the core JSON field."""
deprecated_in = DJANGO_3_1
removed_in = DJANGO_4_0
rename_from = "django.contrib.postgres.fields.JSONField"
rename_to = "django.db.models.JSONField"

But as you noted, the codemodder works only if imported as follow:

from django.contrib.postgres.fields import JSONField

It's true that the field may be imported from jsonb module as well, but I'm not convinced that we should support it... I already identified an edge case if the parent module is imported (#63), but solving these 2 means we would have to support at least 4 different way of importing, and I could see this opening the door to more.

It would be simpler for now to just support one way and maybe never do #63. I like to think that in a near future, what is supported by django-codemod would be enough of an incentive to import things in a predictable way: use documented imports and get the benefit of auto codemodding or do it yourself.

Probably an artifact of the way Pycharm offers imports.

Yes, I'm victim of this one myself, it sometimes suggest to import things from a module I already have in my imports, even if the thing is defined in a totally different location. A bit annoying.

Thanks for your reply.
I'm in two minds about these kind of edge cases of the undocumented kind.
But overall I think you are quite right in this case - support the typical and documented import. It does get caught by manage.py check which means the deprecation doesn't get unreported.

Hum, I think we can leave this open to cover codemodding KeyTransform and KeyTextTransform... Unless they are already handled by django-codemod (I really don't remember)?