-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Django3: add new django.db.models.JSONField
#8868
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Create new JSON fields postfixed with `_json` for all the JSON fields defined via `jsonfield` third party package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks reasonable. Is the plan to then remove the old fields, once we've converted the data? The migration path wasn't clear to me from the description or code.
Ah, I see in #8869 that is likely the plan.
# TODO: now that we are using a proper JSONField here, we could | ||
# probably change this field to be a ForeignKey to avoid repeating the | ||
# config file over and over again and re-use them to save db data as | ||
# well |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, an FK seems reasonable but would be another field right? I agree that our current implementation is just a hacky FK :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. I'm thinking about having something like
# builds.models.Build
config = ForeignKey(BuildConfig)
# config.models.BuildConfig
data = JSONField(default=None)
... and later in the code, I'm expecting to do:
build.config = BuildConfig.objects.get_or_create(data=user_config)
build.save()
and relying on Postgres to do the work about deciding if it's the same or a new one properly 😄
I'm sorry I didn't explain this properly. My idea is to execute this current PR first that will create a new JSON field and populate it with the data we currently have as strings in our db. This step is not destructive and should be safe to deploy. The only concern may be how much time it will take to migrate all the Build's config fields. The next step is #8869 which removes the old config string's fields and renames the new JSON fields so they are now used in production's code. If we do both at the same deploy, we won't need to resync. However, if we only do the first one, we will do to the copy for new Build objects. In theory, it should be safe to do both steps in the same deploy, but these things always scare me 😄 |
This looks like it will still result in some data loss.
I think we should split the migration in two: one creating the fields, and another doing the data migration, and to avoid data loss, we should override the save() methods of the models to populate the new json fields with the information from the old json fields when a model is saved. Then the steps will be as follows:
|
Apply Santos' technique to avoid lossing data while doing the deploy. See #8868 (comment)
Good description of the potential problem 👍 @stsewd I updated this PR to split the migration and overwrite the |
…humitos/new-json-fields
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We just need to make sure to not run all migrations at once during deploy.
I'm not sure if there is an easy way to avoid the downtime from re-naming the fields... but hopefully it should be a quick operation.
Co-authored-by: Santos Gallegos <[email protected]>
I'm moving this out to next's week deploy. |
…humitos/new-json-fields
- cast dict to make them serializable - explicitly declare the fields used for IntegrationForm model - use the default empty dict instead of `None` since it's not allowed in JSON fields
Instead of using JSON as string, we pass a real dict object.
Create new JSON fields postfixed with
_json
for all the JSON fields definedvia
jsonfield
third party package.