jazzband / dj-database-url

Use Database URLs in your Django Application.
https://pypi.org/project/dj-database-url/
BSD 3-Clause "New" or "Revised" License
1.48k stars 205 forks source link

Support unix socket path as host in database url #132

Closed kyle-hamlin closed 1 year ago

kyle-hamlin commented 4 years ago

When running Django applications on Google Cloud serverless products: App Engine, Cloud Functions, and most recently Cloud Run, connecting to Cloud SQL instances requires the use of a unix socket as the database host. This works fine using the traditional DATABASES dict in the settings file:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "postgres",
        "USER": "postgres",
        "PASSWORD": "secret-stuff",
        "HOST": "/cloudsql/<project_id>:<region>:<instance_id>", 
        "PORT": "5432",
    }
}

However dj-database-url doesn't seem to be able to recognize the unix socket path as the host:

import dj_database_url

In [1]: dj_database_url.parse("postgres://postgres:secret-stuff@/cloudsql/<project_id>:<region>:<instance_id>/postgres")
Out[1]:
{'NAME': 'cloudsql/<project_id>:<region>:<instance_id>/postgres',
 'USER': 'postgres',
 'PASSWORD': 'secret-stuff',
 'HOST': '',
 'PORT': '',
 'CONN_MAX_AGE': 0,
 'ENGINE': 'django.db.backends.postgresql_psycopg2'}
frenetic commented 3 years ago

Readme states you can use percent encoding. But it did not work for me. Im trying to set up a dev environment on GCP (cloud run + cloud sql).

juliolvfilho commented 3 years ago

Workaround: You need to encode the HOST part of DATABASE_URL string and then decode again:

import dj_database_url, urllib.parse

# "postgres://" + user + ":" + password + "@" + urllib.parse.quote("/cloudsql/project_id:region:instance_id") + "/" + database
database_url = "postgres://user:password@%2Fcloudsql%2Fproject_id%3Aregion%3Ainstance_id/database"
config = dj_database_url.parse(database_url)
# {
#   'NAME': 'database',
#   'USER': 'user',
#   'PASSWORD': 'password',
#   'HOST': '/cloudsql/project_id%3Aregion%3Ainstance_id',
#   'PORT': '',
#   'CONN_MAX_AGE': 0,
#   'ENGINE': 'django.db.backends.postgresql_psycopg2'
# }
config['HOST'] = urllib.parse.unquote(config['HOST'])
# "/cloudsql/project_id:region:instance_id"

then works!
palfrey commented 1 year ago

Solved by https://github.com/jazzband/dj-database-url/pull/181