I want to use the simple SQLite database on my local environment and use a Postgresql database in production. How can I configure the settings file to know which database to use based on the value of DEBUG?
There are several options available:
Below is a very cheap solution. Django always selects the database called 'default'. You can assign it conditionally in settings.py:
DATABASES = {
'dev': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
},
'production': {
'ENGINE': 'django.db.backends.postgresql',
# ...
},
}
DATABASES['default'] = DATABASES['dev' if DEBUG else 'production']
You can implement an alternate settings module called settings_dev.py. Configure database there and use the environment variable DJANGO_SETTINGS_MODULE to point to yourapp.settings_dev.
Implementing a custom database router. This is almost certainly overkill for many use-cases. See the Django documentation on multiple database support.
Related
I am accessing the remote database in my Django project as follows:
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
},
'remote_db' : {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db_name',
'USER': 'db_user',
'PASSWORD': 'db_password',
'HOST': '192.*.*.*',
'PORT': '1433',
}
}
For accessing default database table's data, I use the following syntax:
from app_name.models import mymodel
mymodel.objects.all()
My remote database has tables like reports, emplayee_data, etc that are already there and my project has no models defined for these tables.
I need to access these tables and I am unsure how to perform this action.
remote_db.reports.all()
All in all, my main objective is to copy the data from remote_db to default database.
Note:
remote_db gets new data everyday.
I think you need to also define models for reports and employee_data in this project.
And then you can use them like the following:
reports.objects.using('remote_db').all()
You mentioned that there are no models defined for the tables. I think it will be a good option to make a script to fetch data from remote_db and add it to default. You will have to use raw SQL to do that if you don't create models for those tables. Another option would be getting the remote_db dump and importing it to the default database.
as the title says, I'm restricted in my development environment. I cannot create extra databases for testing purposes and only create local files.
Using the environ package for django, the configuration of the database is
DATABASES = {
'default': env.db('DATABASE_URL', default='postgres://name#localhost'),
}
As found in this thread, all I need is a "TEST" key in this configuration. It doesn't have one per default so I've bypassed this by writing
db = env.db('DATABASE_URL', default='postgres://name#localhost')
db["TEST"] = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
This doesn't work however. python manage.py test gives me the following output:
Creating test database for alias 'default'...
/usr/lib/python2.7/dist-packages/django/db/backends/postgresql/base.py:267: RuntimeWarning: Normally Django will use a connection to the 'postgres' database to avoid running initialization queries against the production database when it's not needed (for example, when running tests). Django was unable to create a connection to the 'postgres' database and will use the default database instead.
RuntimeWarning
Got an error creating the test database: permission denied to create database
Type 'yes' if you would like to try deleting the test database '/home/<closed environment>/<project>/config/db.sqlite3', or 'no' to cancel:
It still tries to create a database inside an environment in which I do not have the power to alter my own privileges, something that of course fails. I did specify a testing database as a local file but it somehow doesn't use that? Am I overseeing something or am I doing something completely wrong?
After toying around I've found a workaround.
It's not great but it works :\
is_test = "manage.py" in sys.argv and "test" in sys.argv
if is_test:
db = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
else:
db = env.db('DATABASE_URL', default='postgres://name#localhost')
Not gr8, not terrible.
We are a small team, trying to work with Django with a restricted access to a futurely unmanaged PostgreSQL database (i.e: only views and stored procedures ; no access to any tables) for security reasons.
We tried to give (within Postgre) the user external_test the rights to create any tables inside his own schema on external, and to use the following settings (settings.py):
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'external': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgre_db',
'USER': 'external_user',
'PASSWORD': 'password',
'HOST': 'integration.project.net',
'PORT': '5432',
'TEST': {
'NAME': 'test_db',
'USER': 'external_test',
'PASSWORD': 'password',
...
Using simple passing unit tests (project/app/tests/test_views.py):
...
class InternalTest(TestCase):
database = ['default']
def test_something(self):
pass
class StoredProcedureTest(TestCase):
databases = ['external']
def test_one_procedure(self):
with connections["external"].cursor() as cursor:
cursor.callproc("some_procedure", [42, ])
pass
...
If we try the first one with ./manage.py test app.tests.test_views.InternalTest
→ ok
If we try the other one with ./manage.py test app.tests.test_views.StoredProcedureTest
→ circular dependency issue
(ImproperlyConfigured: Circular dependency in TEST[DEPENDENCIES])
probably because it's skipping the configuration of default
If we try both tests with ./manage.py test app.tests.test_views:
→ permission denied
Creating test database for alias 'default'...
Creating test database for alias 'external'...
Got an error creating the test database: permission denied to create database
(Django try to create a database test_db as the user external_user)
We don't really get what Django is trying to do and how to properly configure it.
If we give the rights to external_user to create their own databases:
the database test_db is created by external_user
the schema of default (sqlite) is created in test_db of external (postgre)
the schema of external (postgre) is not created in test_db
Questions
Is django able to handle this ?
What are we doing wrong ?
What is the point of specifying a user external_user for TEST if in the end django is using the normal user external_user ?
Why does it write the schema of default in test_db ? Is there a way to create only models of some apps in it ?
Why isn't it able to create the schema of external in test_db ?
I hope it was described enough. Thank you in advance for your responses =)
I'm creating a django web app that is going to be a database management portal for multiple databases. Because the web app will touch multiple databases, it doesn't make sense to have a default. However, when I run manage.py inspectdb I get an error saying that the ENGINE value isn't set on my database. It most definitely is.
Here's my DATABASES setting in settings.py
DATABASES = {
'default': {
},
'my_db': {
'NAME': 'my_db',
'USER': 'user',
'PASSWORD': 'pass',
'HOST': '192.168.0.255',
'PORT': '',
'ENGINE': 'sql_server.pyodbc',
'OPTIONS': {
'driver': 'ODBC Driver 13 for SQL Server',
},
},
}
If I run manage.py inspectdb using this setup I get this error:
settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.
This doesn't make sense to me, since it says in the documentation that 'default' can be a blank {}.
However, if I supply a dummy NAME and ENGINE variable to the default db, it seems to work fine for the default DB, but it ignores my_db.
If I set default to look at my_db's information I get a login error (so I know at least something is working right there, even if my creds are bad).
So, what am I getting wrong in my database setup here?
You need to specify a database for which you need to inspectdb
python manage.py inspectdb --database your_db_name
For more details see the docs
I have two databases set up in my settings folder of my project
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'foo': {
'NAME': 'bar',
'ENGINE': 'django.db.backends.mysql',
'HOST': 'some.site.com',
'USER': 'xxxxxx',
'PASSWORD': 'xxxxxxxx'
}
I also have models set up, one of them was created with
python manage.py inspectdb --database foo > tmp.py
That created some models I already had in foo, so I copied it over into my models folder. However, django is trying to use the existing default database for that model, when instead I want it to route to the foo database instead.
When looking online for how to get this done. Posts recommend using 'database-routing', but I cannot find documentation or an example that works for me or that I understand.
So please, what is the right way to set up a single model to use an external database?
The easiest way is to select database manually.
From https://docs.djangoproject.com/en/1.8/topics/db/multi-db/#manually-selecting-a-database
>>> # 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()
>>> my_object.save(using='legacy_users')
Documentation has also other options, check: https://docs.djangoproject.com/en/1.8/topics/db/multi-db/