jet-admin / jet-django

Jet Bridge (Django) for Jet Admin – Admin panel framework for your application
https://app.jetadmin.io/demo
Other
194 stars 33 forks source link

Unable to connect to Postgres on a custom socket #19

Open IlyaSemenov opened 4 years ago

IlyaSemenov commented 4 years ago

Currently, there is no way to connect to a Postgres running on a custom socket (e.g. in Google App Engine).

1) with this Django settings.py (as per Django docs):

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "HOST": "/cloudsql/xyz",
        "NAME": "foo",
    }
}

jet-admin fails:

Connected to database engine "postgresql:///cloudsql/xyz/foo"
...
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) FATAL:  database "cloudsql/xyz/foo" does not exist

2) with this Django settings.py:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "foo",
        "OPTIONS": {"host": "/cloudsql/xyz"}
    }
}

jet-admin constructs weird URL and ignores the options:

Connected to database engine "postgresql://foo"
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not translate host name "foo" to address: nodename nor servname provided, or not known

3) with this Django settings.py:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "foo",
        "OPTIONS": {"host": "/cloudsql/xyz"}
    }
}

JET_DATABASE_EXTRA = "?host="/cloudsql/xyz"

it still fails to connect:

Connected to database engine "postgresql://foo?host=/cloudsql/xyz"
...
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not translate host name "foo?host=" to address: nodename nor servname provided, or not known

4) with this Django settings.py:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "HOST": "localhost",
        "NAME": "foo",
        "OPTIONS": {"host": "/cloudsql/xyz"}
    }
}

JET_DATABASE_EXTRA = "?host="/cloudsql/xyz"

it's finally constructing a working connection string:

Connected to database engine "postgresql://localhost/foo?host=/cloudsql/xyz"

but, in this case Django wouldn't connect to the database.

IlyaSemenov commented 4 years ago

With authentication, this gets even weirder. For Django config:

DATABASES = {
    "default": {
        "NAME": "foo",
        "USER": "foo",
        "PASSWORD": "bang",
        "HOST": "",
        "PORT": "",
        "OPTIONS": {"host": "/tmp/myproject:us-east1:foo"},
        "ENGINE": "django.db.backends.postgresql",
    }
}

your build_engine_url returns:

postgresql://foo:bangfoo

🤦

IlyaSemenov commented 4 years ago

Luckily the related code isn't hidden behind layers of closures, so a simple monkey patch would suffice:

import jet_bridge_base.db

jet_bridge_base.db.build_engine_url = lambda conf: env.str("DATABASE_URL")