Why won't Django look for my Postgres schema?!

A few days ago, I never had the problem with connecting to my DB service provider. Everything changed after my service provider migrated from IPv4 to IPv6 and gave my project a new Host and Username.

Simply changing the host and user “should” be enough to resume the connection, but apparently since then Django refuses to connect to the relevant schema.

# settings.py
SUPABASE_SEARCH_PATHS = [
  'project-schema',
  #'public', 
] 

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        # 'ENGINE': 'django.db.backends.postgresql_psycopg2',
        # "ENGINE": f"{PROJECT_NAME}.custom_db_backends.CustomDatabaseWrapper",
       
        "NAME": "postgres",
        "USER": os.getenv('supabase_user'), #"postgres",
        "PASSWORD": os.getenv('supabase_project_pw'),
        "HOST": os.getenv('supabase_project_host_v2'), # supabase has migrated from ipv4 to ipv6
        "PORT": "5432",
        "OPTIONS": {
          'options': f"-c search_path={','.join(SUPABASE_SEARCH_PATHS)}",
        },
    },
}

If I run python manage.py migrate, apparently I will create new tables in “public”, even when I explicitly told it not to from settings.

From python manage.py shell, I tried querying the models and it complains about the lack of a table that was supposed to be from the schema.

>>> from app_user.models import User
>>> users = User.objects.all()
>>> for user in users:
...     print(user)

django.db.utils.ProgrammingError: relation "app_user_user" does not exist
LINE 1: ..."."is_staff", "app_user_user"."is_superuser" FROM "app_user_...

However, if I explicitly connect to that schema and table, I

from django.db import connection

with connection.cursor() as cursor:
    cursor.execute('SELECT * FROM "project-schema".app_user_user')
    rows = cursor.fetchall()
for row in rows:
    print(row)


('pbkdf2_sha256$600000$uVSZ1UIKjQ0wWFmhTHWLap$f/of2NcHSZ2QtwnvqF/EOsvcIXKRvmst3ELrdTGvDWo=', datetime.datetime(2024, 1, 31, 18, 7, 53, 526892, tzinfo=datetime.timezone.utc), '', '', True, datetime.datetime(2024, 1, 19, 19, 2, 14, 239681, 
tzinfo=datetime.timezone.utc), UUID('cd977349-0c5e-4383-ac98-0bbbe7ef803d'), 'example_user', 'example@gmail.com', datetime.datetime(2024, 1, 19, 19, 2, 14, 764524, tzinfo=datetime.timezone.utc), False, False, '01HMHHMBFCG6E51YGHP1JR8S6E'

I was able to get back the results I’m looking for, so it can’t be my db provider’s problem.

Something in django just refuses to search the schema I tells it to, which oddly never happened before I change my Hostname to earlier version.

Side topic: I also tried using a custom database wrapper method (from the parts I’ve commented out), and I could never properly import the engine, even though I have no issues with the path.

# python manage.py shell
>>> from db_backend import custom_backend
>>> from db_backend.custom_backend import CustomDatabaseWrapper
>>> CustomDatabaseWrapper
<class 'db_backend.custom_backend.CustomDatabaseWrapper'>


    raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: 'db_backend.custom_backend.CustomDatabaseWrapper' isn't an available database backend or couldn't be imported. Check the above exception. To use one of the built-in backends, use 'django.db.backends.XXX', where XXX is one of:
    'mysql', 'oracle', 'postgresql', 'sqlite3'
# project/db_backend/custom_backend.py
# (I have __init__.py)
# (I also have registered db_backend in INSTALLED_APPS)

from django.db.backends.postgresql.base import DatabaseWrapper as Psycopg2DatabaseWrapper

class CustomDatabaseWrapper(Psycopg2DatabaseWrapper):
    def get_new_connection(self, conn_params):
        conn = super().get_new_connection(conn_params)
        search_path = "not-public, another_schema"
        with conn.cursor() as cursor:
            cursor.execute(f"SET search_path TO {search_path}")
        return conn

Let’s start from looking at some of the basics:

Please show what versions of Django, Python, and psycopg2 you’re using here. Also, what version of PostgreSQL are you connecting to?

As far as I’m aware, an identifier containing a hyphen must be quoted. Using not-public as a schema name is likely to cause problems in any number of areas.

For example: SET search_path to non-public; throws a syntax error in psql, while SET search_path to "non-public"; works.

(We avoid schema names with hyphens as a result of effects like this.)

I’d try changing the schema names from things like not-public to not_public.