Django 2.2 - Testing which DB my application is connected to [duplicate] - django

This question already has an answer here:
Django: Detect database backend
(1 answer)
Closed 3 years ago.
I'm hoping this will be similar to a few questions which have been previously answered.
I was wondering what the full processes are for testing the DB connection string (not the DB name) for the current connected DB in Django is? I see a few methods for printing the name, but across local development and staging, these names will be the same. I need to know more, such as the db engine (e.g., is it PostgreSQL, or is it db.sqlite3. etc etc), and various other DB parameters.
I'm currently trying to debug why a Celery beat task is failing to create database entries for the application DB I think I am connected to.
I'm performing a simple obj, created = Object.objects.get_or_create() DB method, and on logging created, some are True and some are False. All good so far.
However, the admin section of the Django CMS is not showing any more entries to the DB.
I believe testing the location and connection strings of the DB the Django application is using might be useful in debugging this ghost object creation...unless someone can advise on similar issues they have had with the Celery daemon not actually persisting a DB create/update etc...
Perhaps, something such as:
from django.db import connection
print(connection.settings_dict)
Would be sufficient?

So, the following was useful for determining the DB engine:
from django.db import connection
print(connection.settings_dict)
For useful guidance, the connection.settings_dict contains the following structure:
{
'ENGINE': 'django.db.backends.sqlite3',
'NAME': '/usr/src/app/db.sqlite3',
'ATOMIC_REQUESTS': False,
'AUTOCOMMIT': True,
'CONN_MAX_AGE': 0,
'OPTIONS': {},
'TIME_ZONE': None,
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
'TEST': {
'CHARSET': None,
'COLLATION': None,
'NAME': None,
'MIRROR': None
}
}
So, we could work with something like this in a management command:
from django.db import connection
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = 'Displays The Currently Connected DB Settings'
def handle(self, *args, **kwargs):
print(
"The current database engine is {ENGINE}".format(**connection.settings_dict)
)
print(
"Currently connected to host {HOST} on port {PORT} ".format(**connection.settings_dict)
)

Related

How to communicate with an external server using django application?

Currently I have a requirement,I need to communicate with external server using django application. The server is already up,Next section is the data transfer. I need some time samples and values from server and I need to send responses back to server. How django port can listen to external server.? How it can response back? I need asynchronous communication and REST responses
According to the comments, the external server is a PostgreSQL database.
Since you're using Django, you can easily set this up as a secondary database in your settings:
DATABASES = {
'default': # that SQLite config...,
'game': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': 'somewhere-else',
'PORT': '5432',
},
}
You don't have to route any models to that database, but if you do create any models to correspond to the data in the game server, you'll want to set managed = False so Django doesn't do migrations or anything.
If you don't want to use models, just open a cursor to the secondary database and query away:
from django.db import connections
with connections['game'].cursor() as cursor:
cursor.execute('SELECT something FROM some_table')
# etc...

Concurrency issue? Standalone python script sharing settings.py and ORM with django server has unreliable view of DB objects?

I'm having a strange problem that is difficult to reproduce (everything worked 2 days ago but some time between then and now no longer does--with no changes in the interim!)
I have a django server program which we are running via gunicorn with multiple worker subprocesses and a separate small REST webservice which shares the settings.py of the server program and acts on the same DB objects. The code for this server program is roughly as follows:
# my app's models.py
class TestConfig(models.Model):
## various attributes
class Test(models.Model):
## some attributes
def startTest(self):
return TestExecution.objects.create(test=self)
class TestExecution(models.Model):
test = models.ForeignKey(
Test,
on_delete=models.CASCADE
)
config = models.ForeignKey(
TestConfig,
on_delete=models.CASCADE,
null=True
)
# excerpt from a post() method in my app's views.py
test = Test.objects.get(test_id)
if config_form.is_valid():
config = config_form.save()
config_id = config.id
test_exe = test.startTest()
test_exe.config = config
test_exe.save()
webservice_response = requests.get(
'http://{}:{}/rest/add_to_queue/{}'.format(
webservice_ip, webservice_port, test_exe.id))
The other program (small REST webservice) sharing the same settings.py as the django server program looks as follows:
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
import django
django.setup()
# the REST endpoint referenced from the django server program
#app.route('/rest/add_to_queue/<test_exe_object_id>/')
#app.route('/rest/add_to_queue/<test_exe_object_id>')
def add_to_queue(test_exe_object_id):
from myapp.models import TestExecution
try:
exe_object = TestExecution.objects.get(pk=int(test_exe_object_id))
# for completeness the database section of my settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test_db',
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'localhost',
'PORT': '3306',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
},
}
}
As I mentioned, this was all working fine a few days ago, then when I tried again today I was getting a DoesNotExist in the second program when trying to "get()" the TestExecution object using its 'id'.

OperationalError could not connect to server

I put a Django app on Heroku recently. The home page looks fine, but when I try to go to a page that involves making a query (e.g. p = Photo.objects.get(title=title)), I get this error:
could not connect to server: Connection refused
Is the server running on host "localhost" and accepting
TCP/IP connections on port 5432?
In accordance with this answer, I did $ heroku pg:promote HEROKU_POSTGRESQL_GREEN_URL
Then in my settings.py:
DATABASES = {'default': dj_database_url.config(default=os.environ['DATABASE_URL'])}
Still got the same error, so I tried looking at the results of this (as this answer suggests):
$ heroku run python manage.py shell
>>> from django.conf import settings
>>> print settings.DATABASES['default']
{'TIME_ZONE': 'UTC', 'TEST_MIRROR': None, 'NAME': 'snorthway', 'OPTIONS': {},
'HOST': 'localhost', 'TEST_NAME': None, 'PASSWORD': '******', 'ENGINE':
'django.db.backends.postgresql_psycopg2', 'PORT': '', 'USER': 'snorthway',
'TEST_COLLATION': None, 'TEST_CHARSET': None}
At which point I realized I don't know what I should even be looking for in that. I still don't understand what the error means, so I am unsure how to go about debugging it.
You have not configured your django database correctly in settings.py. It thinks your database is on localhost. Sounds like you have a heroku postgres database so your host should be something like:
df3-64-304-50-250.compute-1.amazonaws.com
Heroku exposes a special database URL through an environment variable called:
DATABASE_URL
There is a very cool python package here called dj_database_url: https://github.com/kennethreitz/dj-database-url it converts that environment variable to what django expects.
you can install it with:
$pip install dj-database-url
I use the following in my settings.py
import dj_database_url
DATABASES = {
'default': dj_database_url.config()
}

django can't drop the test DB via pgbouncer

I'm using pgbouncer with Django. I've added test_foo database to its config to be able to run tests, because apparently Django can't use a different port for the test DB. Now the test run but at the end, when Django tries to drop the test DB, I receive
django.db.utils.DatabaseError: database "test_foo" is being accessed by other users
DETAIL: There are 1 other session(s) using the database.
I suppose that is caused by the open connection stored by pgbouncer. What can I do?
This is not the perfect solution, but it does the trick. You can force Django to use different database settings when running unit tests by adding to your settings.py:
if 'test' in sys.argv or 'test_coverage' in sys.argv:
# Use 5432 as db port (avoid going through pgbouncer, can't delete test DB).
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'xxx',
'USER': 'xxx',
'PASSWORD': 'xxx',
'HOST': '',
'PORT': '5432'
},
}

How to select another DB in Django's ORM when used in a desktop application?

I'm writing a desktop application with PyQt where we planned to use sqlite3-databases for file storage (instead of pickles, XML, YAML, etc). The reason is that our application is likely to migrate to a centralized data store later. (which then needs to communicate with other web based services, etc etc.)
Before everyone says "use SQLAlchemy and Elixir", I'd like to point out why chose Django, namely because:
I know Django pretty well, it's neat and I like it's ORM.
When we migrate, it's easy to add a web-ui on top of it.
Having the Admin-interface makes it easy to debug/inspect the DB during development.
Anyway, my problem is that I can't select different sqlite3 databases, since Django's settings.configure throws an 'already configured' error on the second call.
Any ideas, apart from restarting the app?
(None of many Django-desktop-orm questions here on SO seem to address this...)
Paraphrasing http://docs.djangoproject.com/en/dev/topics/db/multi-db/
Define multiple DBs in the settings.py.
DATABASES = {
'default': {
'NAME': 'defaultdb',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'USER': 'postgres_user',
'PASSWORD': 's3krit'
},
'other': {
'NAME': 'otherdb',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'priv4te'
}
}
Then you can choose the database manually.
>>> # This will run on the 'default' database.
>>> Author.objects.all()
>>> # So will this.
>>> Author.objects.using('default').all()
>>> # This will run on the 'other' database.
>>> Author.objects.using('other').all()