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.
Related
I have an existing PostgreSQL Database and I want to create APIs around it using Django Rest Framework. How do I display the tables in my Database as models in Django to further use them for the API?
First of all, you have to connect the existing DB with your Django application by following those instructions https://docs.djangoproject.com/en/3.1/ref/databases/#postgresql-notes or simply add the code below in your settings.py file
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'db_name',
'USER': 'db_user',
'PASSWORD': 'db_user_password',
'HOST': '',
'PORT': 'db_port_number',
}
}
Secondly, Django provides a powerful command which will help you out to inspect your existing DB models and save those models into your models.py file.
python manage.py inspectdb > models.py
In case that you need more information please read the official documentation https://docs.djangoproject.com/en/3.1/howto/legacy-databases/#auto-generate-the-models.
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.
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 =)
My workplace is planning to use Python/Django as a backend framework and React on the front, on top of oracle db from ASP classic. Since our oracle db structured from the beginning of the company, we decided to keep it as is.
From my understanding, schemas in oracle are typically accessed by username/password, thus need to have user/password for each schema to have an access and our oracle db has about 30ish schemas, containing numerous tables inside for each.
Django, on the other hand, seems it only supports one schema at a time, based on app that is installed in settings.py, which sounds like the databases configuration need to have different user/password set up in settings.py for each app installed.
So far, I've tried class Meta and DATABASES in settings.py;
// class Meta
class SomeModel(models.Model):
///some fields and data types...
class Meta():
managed=False
db_table=u'"schema\".\"table"'
// DATABASES
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'multi_schema_db',
'USER': 'django_user',
'PASSWORD': 'secret',
},
'data': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'multi_schema_db',
'USER': 'data_user',
'PASSWORD': 'secret',
},
}
My questions is, is there any workaround to have an access into multiple schema where django has only one app installed?
P.S. Correct me on any misunderstandings that I have above.
You can have multiple schemas in Django
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'multi_schema_db_1', # The name is the schema
'USER': 'django_user',
'PASSWORD': 'secret',
},
'data': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'multi_schema_db_2', # The name is the schema
'USER': 'data_user',
'PASSWORD': 'secret',
},
}
To use a particular schema you use .using()
SomeModel.objects.using('data').all() # The default is to use the "default" database conection
If some models are only ever in one schema you can use routers to define which database to use for each model
class YourRouter:
def db_for_read(self, model, **hints):
return database_for_the_model
def db_for_write(self, model, **hints):
return database_for_the_model
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/