[Django] #31615: Do not fail migration if postgresql extension is already installed and user is not superuser

14 views
Skip to first unread message

Django

unread,
May 20, 2020, 10:47:51 AM5/20/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: nobody
Type: Bug | Status: new
Component: | Version: 3.0
Migrations | Keywords: migration extension
Severity: Normal | postgresql
Triage Stage: | Has patch: 1
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 1
UI/UX: 0 |
-------------------------------------+-------------------------------------
Currently Django facilitates installing postgres extensions using
migration operations:
https://docs.djangoproject.com/en/3.0/ref/contrib/postgres/operations/

But having a superuser is a tall order in certain environments, and the
manual helpfully points out:

If the Django database user doesn’t have superuser privileges, you’ll have
to create the extension outside of Django migrations with a user that has
the appropriate privileges.

This is fairly often the case with Salt and other orchestration systems.

However having a non-superuser will break any migrations using these
operations because unfortunately `CREATE EXTENSION` even with `IF NOT
EXISTS` still requires superuser privileges... In other words, if the
extension is already in place, the migration will fail...

I think a failsafe like this around CREATE/DROP EXTENSION would make the
migrations more robust and user friendly.

{{{
diff --git a/django/contrib/postgres/operations.py
b/django/contrib/postgres/operations.py
index 0bb131ddf2..46fc11f63f 100644
--- a/django/contrib/postgres/operations.py
+++ b/django/contrib/postgres/operations.py
@@ -21,7 +21,13 @@ class CreateExtension(Operation):
not router.allow_migrate(schema_editor.connection.alias,
app_label)
):
return
- schema_editor.execute("CREATE EXTENSION IF NOT EXISTS %s" %
schema_editor.quote_name(self.name))
+
+ cur = schema_editor.connection.cursor()
+ cur.execute("SELECT * FROM pg_extension WHERE extname = %s",
[self.name])
+ if not cur.fetchone():
+ schema_editor.execute(
+ "CREATE EXTENSION IF NOT EXISTS %s" %
schema_editor.quote_name(self.name)
+ )
# Clear cached, stale oids.
get_hstore_oids.cache_clear()
get_citext_oids.cache_clear()
@@ -33,7 +39,13 @@ class CreateExtension(Operation):
def database_backwards(self, app_label, schema_editor, from_state,
to_state):
if not router.allow_migrate(schema_editor.connection.alias,
app_label):
return
- schema_editor.execute("DROP EXTENSION %s" %
schema_editor.quote_name(self.name))
+
+ cur = schema_editor.connection.cursor()
+ cur.execute("SELECT * FROM pg_extension WHERE extname = %s",
[self.name])
+ if cur.fetchone():
+ schema_editor.execute(
+ "DROP EXTENSION %s" % schema_editor.quote_name(self.name)
+ )
# Clear cached, stale oids.
get_hstore_oids.cache_clear()
get_citext_oids.cache_clear()
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31615>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 20, 2020, 12:16:29 PM5/20/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Migrations | Version: 3.0
Severity: Normal | Resolution:
Keywords: migration extension | Triage Stage: Accepted
postgresql |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Claude Paroz):

* has_patch: 1 => 0
* type: Bug => Cleanup/optimization
* stage: Unreviewed => Accepted


Comment:

I'm in favor. Please check again the `Has patch` box when a GitHub PR is
available.

--
Ticket URL: <https://code.djangoproject.com/ticket/31615#comment:1>

Django

unread,
May 22, 2020, 5:43:20 AM5/22/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Migrations | Version: 3.0
Severity: Normal | Resolution:
Keywords: migration extension | Triage Stage: Accepted
postgresql |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by minusf):

please have a look at this one:
https://github.com/django/django/pull/12952

git got the better of me :/

--
Ticket URL: <https://code.djangoproject.com/ticket/31615#comment:3>

Django

unread,
May 25, 2020, 1:55:56 AM5/25/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Migrations | Version: 3.0
Severity: Normal | Resolution:
Keywords: migration extension | Triage Stage: Accepted
postgresql |
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 1

Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* needs_better_patch: 0 => 1
* needs_tests: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/31615#comment:4>

Django

unread,
May 27, 2020, 1:00:40 AM5/27/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: minusf
Type: | Status: assigned

Cleanup/optimization |
Component: Migrations | Version: 3.0
Severity: Normal | Resolution:
Keywords: migration extension | Triage Stage: Ready for
postgresql | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* owner: nobody => minusf
* needs_better_patch: 1 => 0
* status: new => assigned
* needs_tests: 1 => 0
* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/31615#comment:5>

Django

unread,
May 27, 2020, 5:14:22 AM5/27/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: minusf
Type: | Status: closed

Cleanup/optimization |
Component: Migrations | Version: 3.0
Severity: Normal | Resolution: fixed

Keywords: migration extension | Triage Stage: Ready for
postgresql | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"d693a086def21d843c03ec3f5b5e697ed2463d45" d693a086]:
{{{
#!CommitTicketReference repository=""
revision="d693a086def21d843c03ec3f5b5e697ed2463d45"
Fixed #31615 -- Made migrations skip extension operations if not needed.

- Don't try to create an existing extension.
- Don't try to drop a nonexistent extension.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31615#comment:7>

Django

unread,
May 27, 2020, 5:14:22 AM5/27/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: minusf
Type: | Status: assigned

Cleanup/optimization |
Component: Migrations | Version: 3.0
Severity: Normal | Resolution:
Keywords: migration extension | Triage Stage: Ready for
postgresql | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"f3ed42c8ad3757e7238bf2f326532f5b129aa102" f3ed42c8]:
{{{
#!CommitTicketReference repository=""
revision="f3ed42c8ad3757e7238bf2f326532f5b129aa102"
Refs #31615 -- Improved creating extension docs.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31615#comment:6>

Django

unread,
May 27, 2020, 5:14:55 AM5/27/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: minusf
Type: | Status: closed

Cleanup/optimization |
Component: Migrations | Version: 3.0
Severity: Normal | Resolution: fixed

Keywords: migration extension | Triage Stage: Ready for
postgresql | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"a79d0c8c81847e9ccde42e406bb5b411bab4214a" a79d0c8c]:
{{{
#!CommitTicketReference repository=""
revision="a79d0c8c81847e9ccde42e406bb5b411bab4214a"
[3.1.x] Refs #31615 -- Improved creating extension docs.

Backport of f3ed42c8ad3757e7238bf2f326532f5b129aa102 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31615#comment:8>

Django

unread,
Jun 3, 2020, 1:28:56 AM6/3/20
to django-...@googlegroups.com
#31615: Do not fail migration if postgresql extension is already installed and user
is not superuser
-------------------------------------+-------------------------------------
Reporter: minusf | Owner: minusf
Type: | Status: closed
Cleanup/optimization |
Component: Migrations | Version: 3.0
Severity: Normal | Resolution: fixed
Keywords: migration extension | Triage Stage: Ready for
postgresql | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"22a59c01c00cf9fbefaee0e8e67fab82bbaf1fd2" 22a59c01]:
{{{
#!CommitTicketReference repository=""
revision="22a59c01c00cf9fbefaee0e8e67fab82bbaf1fd2"
Refs #31615 -- Added EXISTS clauses to extension operations.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31615#comment:9>

Reply all
Reply to author
Forward
0 new messages