What is the value of self._db by default in Django? - django

Please see the following code:
user.save(using=self._db)
What is the default value of self._db for Django?
Does this value default to what I've specified under default for database in my settings.py?
I've found questions on Stack Overflow that say this value will provide a database type to Django, but if I've never set it explicitly, what is it by default?

Django default managers use using parameter to define which database underlying the manager should use for operation. This will optionally use. This is used in case you have multiple databases by which you define which database you need to use for operation.
An example user.save(using=self._db) usually defined as "default" from your database configuration in settings.py. For more info click here
Behind the scene self._db set as None. If user.save(using=None), then it will use default database.
For example, your database configuration is like
DATABASES = {
'default': {
'NAME': 'app_data',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'postgres_user',
'PASSWORD': '****'
},
'new_users': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': '****'
}
}
Then if you want to use default database then use user.save(using=self._db)
If you want to use new_users database then use user.save(using="new_users")

Yes, Its default value is specified in settings.py
as
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
as mentioned here

Django default managers use using parameters to define which database underlying the manager should use for operation. This will optionally use. This is used in case you have multiple databases by which you define which database you need to use for operation.
An example user.save(using=self._db) is usually defined as "default" from your database configuration in settings.py.
Behind-the-scene self._db set as None. If user.save(using=None), then it will use the default database.
For example, your database configuration is like
DATABASES = {
'default': {
'NAME': 'app_data',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'postgres_user',
'PASSWORD': '****'
},
'new_users': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': '****'
}
}
Then if you want to use default database then use user.save(using=self._db) If you want to use new_users database then use user.save(using="new_users")

Related

Atomic Database Transactions in Django

I want to have atomic transactions on all the requests in the Django app.
There is the following decorator to add an atomic transaction for one request,
#transaction.atomic
def create_user(request):
....
but then, in this case, I'll have to use this decorator for all the APIs.
I tried doing this in settings.py:
DATABASES = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'blah',
'USER': 'postgres',
'PASSWORD': 'blah',
'HOST': '0.0.0.0',
'PORT': '5432',
'ATOMIC_REQUESTS': True
}
But adding ATOMIC_REQUESTS does not seem to work in some cases.
Is there any way so that I can apply atomic transactions for all APIs?
Not quite sure if this the case but in the documentation, explains that you need to pass 'using' param to this decorator which is what database this operation applies to.
so
can you try this
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'blah',
'USER': 'postgres',
'PASSWORD': 'blah',
'HOST': '0.0.0.0',
'PORT': '5432',
'ATOMIC_REQUESTS': True,
},
}
then like this:
#transaction.atomic(using='default')
def create_user(request):
I also realized that you used psycopg2 as your engine
Changed in Django 1.9:
from the docs:
The django.db.backends.postgresql backend is named
django.db.backends.postgresql_psycopg2 in older releases. For
backwards compatibility, the old name still works in newer versions.
fyi

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

Trigger Django Signal from Different Database other than default db

I have different database other than default.
#receiver(post_save, sender=Customer)
def customer_post_save_task(sender, instance, created, **kwargs):
print("hmm", created)
But This only triggers when Customer is created from default db
If Customer is created from another db it does not get invoked.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'mydb': {
'ENGINE': 'django.contrib.gis.db.backends.mysql',
'NAME': 'mydb',
'USER': 'root',
'PASSWORD': 'test',
'HOST': 'localhost',
'PORT': '3306',
}
When customer is created in mydb signal doesnot trigger. What can I do?

Alloting a read replica to a particular app in Django?

The django project has multiple apps and they all right now access the same DB. If I want one app which has only read queries to read from read replica will I have to add routers for both DB or creating one router for read replica and alloting it to the app will work? Is there a better way to do this?
you can use multiple database as defined in documentation:
https://docs.djangoproject.com/en/2.0/topics/db/multi-db/
Ex:
DATABASES = {
'default': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'password1'
},
'read_replica': {
'NAME': 'customer_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_cust',
'PASSWORD': 'password2'
}
}
After use a Database Router (django.db.router):
https://docs.djangoproject.com/en/2.0/topics/db/multi-db/#using-routers
There is a DATABASE_ROUTERS config as well.

how to integrate mysql as primary database and mongodb as secondary database

I am working on a Django project where I need to use both mysql/postgresql as well as mongoDB, one as primary and one as secondary database. How do I configure my db settings to use two databases?
I am able to use 1 database as postgresql or mongoDB, but not able to use both. I have provided the code below of what I have tried.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'HOST': os.environ.get("DB_HOST", DB_HOST),
'PORT': os.environ.get('DB_PORT', DB_PORT),
'NAME': os.environ.get("DB_NAME", DB_NAME),
'USER': os.environ.get("DB_USER", DB_USER),
'PASSWORD': os.environ.get("DB_PASSWORD", DB_PASSWORD),
},
}
I have figured out the solution to this. We would need to use a third party plugin called Django MongoDB Engine.
Documentation: https://django-mongodb-engine.readthedocs.io/en/latest/topics/setup.html
'default': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'priv4te'
},
'mongo' : {
'ENGINE' : 'django_mongodb_engine',
'NAME' : 'my_database'
}
}```