[Django]-How install a extension in postgresql before creating the models in django?

14๐Ÿ‘

โœ…

I know this is unanswered for long, and maybe now you already have figured out the answer. But Iโ€™m posting just in case someone gets a little bit of help from this.

For extensions that are available in Postgres

If the extension is one of the defaults that are available with Postgres, then you can simply create first migration as this, and then load other migrations.

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib.postgres.operations import HStoreExtension

from django.db import migrations


class Migration(migrations.Migration):

    run_before = [
        ('some_app_that_requires_hstore', '0001_initial'),
    ]

    operations = [
        HStoreExtension(),
    ]

Notice the use of run_before. It is the exact opposite of dependencies. Alternatively, you can make this migration as say 1st one and load all others after this using dependencies.

In case this migration fails to create an extension because of privileges issues, then you can simply use the superuser and nosuperuser in Postgres to temporarily provide privileges for the current user to run migrations like:

ALTER ROLE user_name superuser;
# create the extension and then remove the superuser privileges.
ALTER ROLE user_name nosuperuser;

For third-party extensions that are not available in Postgres

For third-party extensions, you can use run_python, to load the extension for you like:

from django.db import migrations


def create_third_party_extension(apps, schema_editor):
    schema_editor.execute("CREATE EXTENSION my_custom_extension;")


def drop_third_party_extension(apps, schema_editor):
    schema_editor.execute("DROP EXTENSION IF EXISTS my_custom_extension;")


class Migration(migrations.Migration):

    dependencies = [
        ('venues', '0001_auto_20180607_1014'),
    ]

    operations = [
        migrations.RunPython(create_third_party_extension, reverse_code=drop_third_party_extension, atomic=True)
]

Alternatively, you can just have them as a part of your deployment scripts instead of migrations.

I hope this helps.

๐Ÿ‘คSanyam Khurana

0๐Ÿ‘

You can also install the extension on the template database, and when new databases are created (like when running tests), the new database will copy that template and include the extension.

psql -d template1 -c 'create extension if not exists hstore;'
๐Ÿ‘คrobert wallace

0๐Ÿ‘

For django 3+ you can use migrations.RunSQL:

class Migration(migrations.Migration):

    dependencies = [
        ('some_app_that_requires_hstore', '0001_initial'),
    ]

    operations = [
        migrations.RunSQL('CREATE EXTENSION ltree;'),
        migrations.AddConstraint(
            ...
        ),
    ]
๐Ÿ‘คnmzgnv

Leave a comment