Django 4.0.1 authentication from not default database - django

I create project using DRF, I'm using two database alias: Default and Oracle. On oracle database there are all django tables. How can I use authenticate if auth_user is on oracle not default database.

Hello as seen by the documentation of Django you can run multiple databases but you need to re-write most of your Serializers/Views depending on the models you need to retrive/write/delete.
Here is the link of the documentation:
https://docs.djangoproject.com/en/4.0/topics/db/multi-db/
>>> # This will run on the 'default' database.
>>> Author.objects.all()
>>> # So will this.
>>> Author.objects.using('default').all()
>>> # This will run on the 'replica1' database.
>>> Author.objects.using('replica1').all()
DATABASES = {
'default': {},
'auth_db': {
'NAME': 'auth_db_name',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'swordfish',
},
'primary': {
'NAME': 'primary_name',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'spam',
},
'replica1': {
'NAME': 'replica1_name',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'eggs',
},
'replica2': {
'NAME': 'replica2_name',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'bacon',
},
}

Related

How can I toggle databases in Django?

Django's settings.py file has a DATABASES dictionary that stores configuration information for any number of database backends:
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'test': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'testing',
'USER': 'bert',
'PASSWORD': '***',
'HOST': 'remotemysql.com',
'PORT': '3306',
},
'dev': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'development',
'USER': 'ernie',
'PASSWORD': '***',
'HOST': 'remotemysql.com',
'PORT': '3306',
},
...
}
I would expect the Django authors to have included a method to easily switch among these configuration options, such as a separate variable somewhere
USE_THIS_DB = 'test';
in order to easily switch between testing, development, production, etc. databases.
I can't find this option. The only information I can find about switching databases is to manually rename the different configuration options in DATABASES so that the one I want to use is called default, which seems unnecessarily clunky, error-prone, and non-portable.
Is there no way to more elegantly switch Django among different databases at startup?
Why not just DIY in Python ?
# settings.py
DATABASES = {
'test': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'testing',
'USER': 'bert',
'PASSWORD': '***',
'HOST': 'remotemysql.com',
'PORT': '3306',
},
'dev': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'development',
'USER': 'ernie',
'PASSWORD': '***',
'HOST': 'remotemysql.com',
'PORT': '3306',
},
'sqlite': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
}
USE_THIS_DB = 'test'
DATABASES['default'] = DATABASES[USE_THIS_DB]

Django oracle database connection

Im facing issue while connecting to oracle db in django project,
Oracle connection details:
'''
XXXX=
  (DESCRIPTION =
  (LOAD_BALANCE = YES)
  (FAILOVER = YES)
  (ADDRESS_LIST =
  (ADDRESS = (COMMUNITY = XXX.xxxx)
  (PROTOCOL = TCP)
  (Host = xxx-xx.xxx.com)(Port = 1521)))
  (CONNECT_DATA =
  (service_name = xxxx.xxxxx)))
'''
i want to fit oracle details in below django database connection code,
'''
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'xe',
'USER': 'a_user',
'PASSWORD': 'a_password',
'HOST': 'dbprod01ned.mycompany.com',
'PORT': '1540',
}
}
'''
Welcome to StackOverflow!
From the Doc. If tnsnames.ora isn't being used.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': '(DESCRIPTION=(LOAD_BALANCE=YES)(FAILOVER=YES)(ADDRESS_LIST=(ADDRESS=(COMMUNITY=XXX.xxxx)(PROTOCOL=TCP)(Host=xxx-xx.xxx.com)(Port=1521)))(CONNECT_DATA=(service_name=xxxx.xxxxx)))',
'USER': 'a_user',
'PASSWORD': 'a_password',
'HOST': '',
'PORT': '',
}
}
Or you have made sure your oracle client has tnsnames configured
tnsnames.ora
MY_AWESOME_TNS_ALIAS=(DESCRIPTION=(LOAD_BALANCE=YES)(FAILOVER=YES)(ADDRESS_LIST=(ADDRESS=(COMMUNITY=XXX.xxxx)(PROTOCOL=TCP)(Host=xxx-xx.xxx.com)(Port=1521)))(CONNECT_DATA=(service_name=xxxx.xxxxx)))
Now django can be configured by alias name. You hide the connection-details from the django application.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'MY_AWESOME_TNS_ALIAS',
'USER': 'a_user',
'PASSWORD': 'a_password',
'HOST': '',
'PORT': '',
}
}
Best of luck!

Django how to use separate database for default authentication

I have a database created from non-django app and have defined the database connection info like below
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('POSTGRES_DB'),
'USER': os.environ.get('POSTGRES_USER'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
'HOST': os.environ.get('POSTGRES_HOST'),
'PORT': os.environ.get('POSTGRES_PORT'),
}
}
Unfortunately, when I migrate the django admin related tables, they all go into the default database.
I know that it is possible to declare multiple databases and separate read and write actions to different databases; however, what I would like to do is to have all the default django admin related tables to be created into another database. Say I declare a second database like below, how do I make sure that django admin related datas get migrated to the second database and also read from that when I login to django admin?
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('POSTGRES_DB'),
'USER': os.environ.get('POSTGRES_USER'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
'HOST': os.environ.get('POSTGRES_HOST'),
'PORT': os.environ.get('POSTGRES_PORT'),
},
'admin':{
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('ADMIN_POSTGRES_DB'),
'USER': os.environ.get('ADMIN_POSTGRES_USER'),
'PASSWORD': os.environ.get('ADMIN_POSTGRES_PASSWORD'),
'HOST': os.environ.get('ADMIN_POSTGRES_HOST'),
'PORT': os.environ.get('ADMIN_POSTGRES_PORT'),
}
}
first you must leave default dictionary as empty
then define your database for admin and non admin
for examample do this
DATABASES = {
'default':{},
'nonAdmin': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('POSTGRES_DB'),
'USER': os.environ.get('POSTGRES_USER'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
'HOST': os.environ.get('POSTGRES_HOST'),
'PORT': os.environ.get('POSTGRES_PORT'),
},
'admin':{
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('ADMIN_POSTGRES_DB'),
'USER': os.environ.get('ADMIN_POSTGRES_USER'),
'PASSWORD': os.environ.get('ADMIN_POSTGRES_PASSWORD'),
'HOST': os.environ.get('ADMIN_POSTGRES_HOST'),
'PORT': os.environ.get('ADMIN_POSTGRES_PORT'),
}
}
then after that you can migrate database using
./manage.py migrate --database=admin
or
./manage.py migrate --database=nonAdmin
If you don’t want every application to be synchronized onto a particular database, you can define a database router that implements a policy constraining the availability of particular models.
by using this method
allow_migrate(db, app_label, model_name=None, **hints)
you can reference this document https://docs.djangoproject.com/en/3.0/topics/db/multi-db/#topics-db-multi-db-routing

Django - Adding a second database entry causes failure. Django no longer uses 'default'

My database and project work great using this database setting:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectuser',
'PASSWORD': 'my_secret_password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
},
}
But I want to add a 'readonly' database entry for my readonly db user, like this, so that I can run django-sql-explorer:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectuser',
'PASSWORD': 'my_secret_password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
},
'readonly': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectreadonly',
'PASSWORD': 'your_eyes_only_secret',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
}
}
And now django throws a couple different errors. If I try to do anything with migrations, I get:
django.db.utils.ProgrammingError: permission denied for relation django_migrations
If I try to runserver, I get:
"AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'users.User' that has not been installed
It seems like when I add the second database setting, django is attempting to use that for migrations, running the server, etc, even though it's not 'default'
If I comment out the second entry, everything works great again.
Any recommendations on how to correct this?
Edit: If I change the settings to use the same username and password, everything works great, so it's not just an issue of django being confused on names. IE:
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectuser',
'PASSWORD': 'my_secret_password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
},
'readonly': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'myprojectdb',
'USER': 'myprojectuser',
'PASSWORD': 'my_secret_password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True
}
}
The two configurations shares the same database names 'NAME': 'myprojectdb'
So when you try to migrates dbname seems to conflicts so the applications is having an indecision on which to use The previous or the later

Django - Using PostGIS database with PostgreSQL database, do I need 2 databases?

I'm currently using a single PostgreSQL database, with standard settings.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': password,
'HOST': 'localhost',
'PORT': '',
}
}
My question is, can I keep using the default postgres setup, and just perform CREATE EXTENSION postgis in the shell to get access to postgis features? Or do I need to add a postgis database separately, like below:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': password,
'HOST': 'localhost',
'PORT': '',
}
'geodata': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'geodjango',
'USER': 'geo',
},
}
You can keep using the default postgres setup, just changing the engine to: django.contrib.gis.db.backends.postgis
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': password,
'HOST': 'localhost',
'PORT': '',
}
}