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