Skip to content

Commit

Permalink
Merge pull request #97 from jazzband/fix/django-migrartions
Browse files Browse the repository at this point in the history
bug fixes and support several features for django migrations
  • Loading branch information
shimizukawa committed Feb 26, 2022
2 parents 392a096 + 63a4921 commit a40e6a4
Show file tree
Hide file tree
Showing 10 changed files with 894 additions and 194 deletions.
32 changes: 31 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,46 @@ General:
* #87 Drop py2 wheel tag from release package file.
* Add `CODE_OF_CONDUCT.rst` The linked text which has been referred to from CONTRIBUTING.rst is now included.

Incompatible Changes:

* #97 To specify SORTKEY for Redshift, you must use `django_redshift_backend.SortKey` for
`Model.Meta.ordering` instead of bearer string.

**IMPORTANT**:
With this change, existing migration files that specify ordering are not affected.
If you want to apply SortKey to your migration files, please comment out the ordering option once and run
makemigrations, then comment in the ordering option and run makemigrations again.

* #97 `django_redshift_backend.distkey.DistKey` is moved to `django_redshift_backend.DistKey`.
However old name is still supported for a compatibility.

* #97 Now django-redshift-backend doesn't support `can_rollback_ddl`.
Originally, Redshift did not support column name/type(size) changes within a transaction.
Please refer https://github.com/jazzband/django-redshift-backend/issues/96

* #97 changed the behavior of implicit not null column addition.
previously, adding a not null column was implicitly changed to allow null.
now adding not null without default raises a programmingerror exception.

Bug Fixes:

* #92, #93: since django-3.0 sqlmigrate (and migrate) does not work.
* #90, #13: fix database inspection capability with `manage.py inspectdb`. Thanks to Matt Fisher.
* #37: fix Django `contenttype` migration that cause `ProgrammingError: cannot drop sortkey column
"name"` exception.
* #64: fix Django `auth` migration that cause `NotSupportedError: column "content_type__app_label"
specified as distkey/sortkey is not in the table "auth_permission"` exception.

Features:

* #82 Add Python-3.10 support.
* #82 Drop Django-3.0 support.
* #90, #13: Support `manage.py inspectdb`, also support working with the django-sql-explorer package.
Thanks to Matt Fisher.
* #63 Support changing a field from NOT NULL to NULL on migrate / sqlmigrate.
* #97 Support VARCHAR size changing for UNIQUE, PRIMARY KEY, FOREIGN KEY.
* #97 Support backward migration for DROP NOT NULL column wituout DEFAULT.
One limitation is that the DEFAULT value is set to match the type. This is because the only way for
Redshift to add NOT NULL without default is to recreate the table.

2.1.0 (2021/09/23)
------------------
Expand Down
2 changes: 2 additions & 0 deletions django_redshift_backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@
except DistributionNotFound:
# package is not installed
pass

from django_redshift_backend.meta import DistKey, SortKey # noqa
643 changes: 479 additions & 164 deletions django_redshift_backend/base.py

Large diffs are not rendered by default.

20 changes: 3 additions & 17 deletions django_redshift_backend/distkey.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
from __future__ import absolute_import

from django.db.models import Index


class DistKey(Index):
"""A single-field index denoting the distkey for a model.
Use as follows:
class MyModel(models.Model):
...
class Meta:
indexes = [DistKey(fields=['customer_id'])]
"""
pass
# flake8: noqa
# for backward compatibility before 3.0.0
from .meta import DistKey
45 changes: 45 additions & 0 deletions django_redshift_backend/meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from django.db.models import Index


class DistKey(Index):
"""A single-field index denoting the distkey for a model.
Use as follows:
class MyModel(models.Model):
...
class Meta:
indexes = [DistKey(fields=['customer_id'])]
"""
def deconstruct(self):
path, expressions, kwargs = super().deconstruct()
path = path.replace('django_redshift_backend.meta', 'django_redshift_backend')
return (path, expressions, kwargs)


class SortKey(str):
"""A SORTKEY in Redshift, also valid as ordering in Django.
https://docs.djangoproject.com/en/dev/ref/models/options/#django.db.models.Options.ordering
Use as follows:
class MyModel(models.Model):
...
class Meta:
ordering = [SortKey('created_at'), SortKey('-id')]
"""
def __hash__(self):
return hash(str(self))

def deconstruct(self):
path = '%s.%s' % (self.__class__.__module__, self.__class__.__name__)
path = path.replace('django_redshift_backend.meta', 'django_redshift_backend')
return (path, [str(self)], {})

def __eq__(self, other):
if self.__class__ == other.__class__:
return self.deconstruct() == other.deconstruct()
return NotImplemented
13 changes: 8 additions & 5 deletions doc/refs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,21 +92,24 @@ Django Models
Using sortkey
-------------

There is built-in support for this option for Django >= 1.9. To use `sortkey`, simply define an `ordering` on the model meta as follow::
There is built-in support for this option for Django >= 1.9. To use `sortkey`, define an `ordering` on the model
meta with the custom sortkey type `django_redshift_backend.SortKey` as follow::

class MyModel(models.Model):
...

class Meta:
ordering = ['col2']
ordering = [SortKey('col2')]

`SortKey` in `ordering` are also valid as ordering in Django.

N.B.: there is no validation of this option, instead we let Redshift validate it for you. Be sure to refer to the `documentation <http://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_examples.html>`_.

Using distkey
-------------

There is built-in support for this option for Django >= 1.11. To use `distkey`, define an index on the model
meta with the custom index type `django_redshift_backend.distkey.DistKey` with `fields` naming a single field::
meta with the custom index type `django_redshift_backend.DistKey` with `fields` naming a single field::

class MyModel(models.Model):
...
Expand Down Expand Up @@ -143,7 +146,7 @@ That is, to go from::
...
migrations.AddIndex(
model_name='facttable',
index=django_redshift_backend.distkey.DistKey(fields=['distkeycol'], name='...'),
index=django_redshift_backend.DistKey(fields=['distkeycol'], name='...'),
),
]

Expand All @@ -160,7 +163,7 @@ To::
...
],
options={
'indexes': [django_redshift_backend.distkey.DistKey(fields=['distkeycol'], name='...')],
'indexes': [django_redshift_backend.DistKey(fields=['distkeycol'], name='...')],
},
),
...
Expand Down
4 changes: 2 additions & 2 deletions examples/proj1/testapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django.db import models

from django_redshift_backend.base import DistKey
from django_redshift_backend.base import DistKey, SortKey


class TestModel(models.Model):
Expand All @@ -23,7 +23,7 @@ class TestModelWithMetaKeys(models.Model):

class Meta:
indexes = [DistKey(fields=['fk'])]
ordering = ['created_at', '-id']
ordering = [SortKey('created_at'), SortKey('-id')]


class TestParentModel(models.Model):
Expand Down

0 comments on commit a40e6a4

Please sign in to comment.