Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using RedShift as an additional Django Database

I have two Databases defined, default which is a regular MySQL backend andredshift (using a postgres backend). I would like to use RedShift as a read-only database that is just used for django-sql-explorer.

Here is the router I have created in my_project/common/routers.py:

class CustomRouter(object):
    def db_for_read(self, model, **hints):
        return 'default'

    def db_for_write(self, model, **hints):
        return 'default'

    def allow_relation(self, obj1, obj2, **hints):
        db_list = ('default', )
        if obj1._state.db in db_list and obj2._state.db in db_list:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        return db == 'default'

And my settings.py references it like so:

DATABASE_ROUTERS = ['my_project.common.routers.CustomRouter', ]  

The problem occurs when invoking makemigrations, Django throws an error with the indication that it is trying to create django_* tables in RedShift (and obviously failing because of the postgres type serial not being supported by RedShift:

...
raise MigrationSchemaMissing("Unable to create the django_migrations table (%s)" % exc)

django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table (Column "django_migrations.id" has unsupported type "serial".)

So my question is two-fold:

  1. Is it possible to completely disable Django Management for a database, but still use the ORM?
  2. Barring Read-Only Replicas, why has Django not considered it an acceptable use case to support read-only databases?

Related Questions

- Column 'django_migrations.id' has unsupported type 'serial' [ with Amazon Redshift]

like image 758
Daniel van Flymen Avatar asked Nov 30 '16 16:11

Daniel van Flymen


1 Answers

I just discovered that this is the result of a bug. It's been addressed in a few PRs, most notably: https://github.com/django/django/pull/7194

So, to answer my own questions:

  1. No. It's not currently possible. The best solution is to use a custom Database Router in combination with a read-only DB account and have allow_migrate() return False in the router.
  2. The best solution is to upgrade to Django >= 1.10.4 and not use a Custom Database Router, which stops the bug. However, this is a caveat if you have any other databases defined, such as a Read-Replica.
like image 98
Daniel van Flymen Avatar answered Oct 14 '22 09:10

Daniel van Flymen