How to connect to existing oracle db table in Django - python

Actually, i am developing UI for my team for daily Data visualization using Django, but from last two week i have searched a lot in google, i didn't get solution, even i have followed Django Documentation for connecting Oracle DB.
Already i have date in my Metrics table, i don't want create a table again. can anyone help me to connect existing Oracle DB OtherUser table in Django and how to write in model.py.
i have installed cx_Oracle library also.
i have tried inspectin DB its show as below.
from django.db import models
Unable to inspect table 'METRICS'
The error was: ORA-00942: table or view does not exist
# setting.py
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'servicename',
'USER': 'mysuer',
'PASSWORD': 'mypassword',
'SCHEMAS': 'SCHEMANAME',
}
# models.py
class Metrics(models.Model):
class Meta:
db_table = '"SCHEMANAME"."METRICS"'
verbose_name = 'Metrics'
verbose_name_plural = 'Metrics'
i have test in single test.py file i am able to get the data using cursor in cx_oracle, but how i can do it in django?

Related

Retrieving data from Mongodb and show it on front-end using django

I have a mongodb database named as world, which has two collection from before city, languages. I want to show the data of my collection on the web, how can i do it.
currently i know to create collection in models.py and migrate it. like;
first we have to edit databases[] in setting.py
DATABASES = {
'default': {
'ENGINE': 'djongo',
'NAME': 'world',
}
}
in models.py i creted a class and migrated it using python manage.py migrate
class Destination(models.Model):
name= models.CharField(max_length=100)
img=models.ImageField(upload_to='pics')
desc=models.TextField()
and i'm able to retrieve data from Destination by using below code in views.py
from django.shortcuts import render
from .models import Destination
def index(request):
dests=Destination.objects.all()
return render(request,'index.html',{'dests':dests})
My question is my collection/class is already available in the database ( city, language) and i'm not creating it contrary to Destination which was defined by me. then how to show data of city collection of world database on the front-end.
kindly looking for help.
If I got you properly, then you have a MongoDB database called world.
There you stored city and languages before you started to set up Django.
Then you added a Destination model, thus created a new collection.
For now, you're looking for a way how to get city and languages collections data similar way as you do with Destination.
So there are multiple ways how you could handle it:
Create Django models for city and languages collections (define fields that you have in existing collections):
class City(models.Model):
field1 = ...
field2 = ...
class Meta:
db_table = 'city' # important, should be your existing collection name
class Language(models.Model):
field3 = ...
field4 = ...
class Meta:
db_table = 'languages' # important, should be your existing collection name
Now you're ready to use City and Language the same way as you do with the Destination model.
Use PyMongo (this is already installed as you're using Djongo). So your snipped will look something like:
from django.shortcuts import render
from .models import Destination
import pymongo
# default localhost connection URL
MONGO_URL = 'mongodb://localhost:27017'
connection = pymongo.MongoClient(MONGO_URL)
mongo_db = connection.world
def index(request):
collection_city = db['city']
collection_languages = db['languages']
cities = list(collection_city.find())
languages = list(collection_languages.find())
dests=Destination.objects.all()
return render(
request,
'index.html',
{
'dests': dests,
'cities': cities,
'languages': languages
}
)
I'd use option 1, as it allows you to keep the project coherent.

I can connect an application to 2 databases in Django?

I have a web application in Python django. I need to import users and display data about them from another database, from another existing application. All I need is the user to be able to login and display information about them. What solutions are?
You can set 2 DATABASES in settings.py.
DATABASES = {
'default': {
...
},
'user_data': {
...
}
}
Then in one database store User models with authentication and stuff, in another rest information. You can connect information about specific User with a field that is storing id of User from another database.
If you have multiple databases and create a model, you should declare on which db it is going to be stored. If you didn't, it will be in default one (if you have it declared).
class UserModel(models.Model):
class Meta:
db_table = 'default'
class UserDataModel(models.Model):
class Meta:
db_table = 'user_data'
the answer from #NixonSparrow was wrong.
_meta.db_table defined only table_name in database and not the database self.
for switch database you can use manager.using('database_name'), for every model, it is good declared here: https://docs.djangoproject.com/en/4.0/topics/db/multi-db/#topics-db-multi-db-routing
in my project i use multiple router.
https://docs.djangoproject.com/en/4.0/topics/db/multi-db/#topics-db-multi-db-routing
it help don't override every manager with using. But in your case:
DATABASES = {
'default': {
...
},
'other_users_data': {
...
}
}
and somethere in views:
other_users = otherUserModel.objects.using('other_users_data')
Probably, otherUserModel should define in meta, which table you want to use db_table = 'other_users_table_name' and also probably it should have managed=False, to hide this model from migration manager.

Django ORM: How to query secondary database which is in read-only mode and no reference in model.py file

I want to query secondary database which is basically a production database. Currently I am using direct query but want to use ORM.
My current models.py file looks like below. Here user is providing TABLE name. For simplicity consider TABLE is "SERVER_LIST".
from django.db import connections
# Create your models here.
def my_custom_sql(TABLE):
with connections["my_oracle"].cursor() as cursor:
cursor.execute("select * from {0} where server = 'XYZ';".format(TABLE))
row = cursor.fetchall()
return row
Database entry:setttings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'mydatabase',
},
'my_oracle': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'xyz:1234/ABCDB',
'USER': 'ABC',
'PASSWORD': '1234'
},
}
I want to run same query using Django ORM. Can someone help how to connect to secondary database and create models.py file for this database. I refer to this link but it imports model.py file which i dont think is possible in my case as database is already existing and in read-only mode.
Your DATABASES variable in your settings.py file should look something like this:
DATABASES = {
'default': DEFAULT_DB_CONFIG,
'slave': SLAVE_DB_CONFIG,
}
and when you are using ORM and want to query a table, you can use using interface like below:
SampleModel.objects.using('slave').all()
Check documentation: https://docs.djangoproject.com/en/3.0/topics/db/multi-db/

django with multiple databases and foreignkeys for User

Suppose I have a django app on my server, but I wish to do authentication using django.contrib.auth.models where the User and Group models/data are on another server in another database. In Django, my DATABASES setting would be something like this:
DATABASES = {
'default': {},
'auth_db': {
'NAME' : 'my_auth_db',
'ENGINE' : 'django.db.backends.mysql',
'USER' : 'someuser',
'PASSWORD' : 'somepassword',
'HOST' : 'some.host.com',
'PORT' : '3306',
},
'myapp': {
'NAME': 'myapp_db',
'ENGINE': 'django.db.backends.mysql',
'USER': 'localuser',
'PASSWORD': 'localpass',
}
}
DATABASE_ROUTERS = ['pathto.dbrouters.AuthRouter', 'pathto.dbrouters.MyAppRouter']
First question: will this work, ie will it allow me to login to my Django app using users that are stored in the remote DB 'my_auth_db'?
Assuming the answer to the above is yes, what happens if in my local DB (app 'myapp') I have models that have a ForeignKey to User? In other words, my model SomeModel is defined in myapp and should exist in the myapp_db, but it have a ForeignKey to a User in my_auth_db:
class SomeModel(models.model):
user = models.ForeignKey(User, unique=False, null=False)
description = models.CharField(max_length=255, null=True)
dummy = models.CharField(max_length=32, null=True)
etc.
Second question: Is this possible or is it simply not possible for one DB table to have a ForeignKey to a table in another DB?
If I really wanted to make this work, could I replace the ForeignKey field 'user' with an IntegerField 'user_id' and then if I needed somemodel.user I would instead get somemodel.user_id and use models.User.objects.get(pk=somemodel.user_id), where the router knows to query auth_db for the User? Is this a viable approach?
The answer to question 1 is: Yes.
What you will need in any case is a database router (The example in the Django docs is exactly about the auth app, so there's no need to copy this code here).
The answer to question 2 is: Maybe. Not officially. It depends on how you have set up MySQL:
https://docs.djangoproject.com/en/dev/topics/db/multi-db/#limitations-of-multiple-databases
Django doesn’t currently provide any support for foreign key or many-to-many relationships spanning multiple databases.
This is because of referential integrity.
However, if you’re using SQLite or MySQL with MyISAM tables, there is no enforced referential integrity; as a result, you may be able to ‘fake’ cross database foreign keys. However, this configuration is not officially supported by Django.
I have a setup with several legacy MySQL DBs (readonly). This answer shows How to use django models with foreign keys in different DBs?
I later ran into troubles with Django ManyToMany through with multiple databases and the solution (as stated in the accepted answer there) is to set the table name with quotes:
class Meta:
db_table = '`%s`.`table2`' % db2_name
Related questions that might provide some additional information:
How to work around lack of support for foreign keys across databases in Django
How to use django models with foreign keys in different DBs?
It would be nice if somebody would take all this information and put in into the official Django doc :-)

Django testing MS-SQL legacy database with stored procedures

In Django I would like to use Unit Test for testing a MS-SQL Server legacy database. The database is using stored procedures for adding data. The situation is as follow:
The MS-SQL database has the following settings in Django:
DATABASES['vadain_import'] = {
'ENGINE': 'sql_server.pyodbc',
'USER': 'xx',
'PASSWORD': 'xxx',
'HOST': '192.168.103.102',
'PORT': '',
'NAME': 'Vadain_import',
'OPTIONS': {
'driver': 'SQL Server Native Client 11.0',
'MARS_Connection': True,
}
}
The models of the database are made with inspectdb, example:
class WaOrders(models.Model):
order_id = models.IntegerField(primary_key=True, db_column='intOrderId')
type = models.TextField(db_column='chvType', blank=True)
class Meta:
db_table = 'WA_ORDERS'
database_name = 'vadain_import'
managed = False
# (There's a lot more of properties and models)
In models is executing the stored procedures. I cann't use the save
functionality of Django, like WAOrders.save(), because in the MS-SQL
database the primary key's are generated in the stored procedure.
#classmethod
def export(cls, **kwargs):
# Stored procedure for adding data into the db
sql = "declare #id int \
set #id=0\
declare #error varchar(1000)\
set #error=''\
exec UspWA_OrderImport\
#intOrderId=#id out\
,#chvType=N'%s'" % kwargs['type'] + " \
,#chvErrorMsg=#error output\
select #id as id, #error as 'error' \
"
# Connection Vadain db
cursor = connections['vadain_import'].cursor()
# Execute sql stored procedure, no_count is needed otherwise it's returning an error
# Return value primary key of WAOrders
try:
cursor.execute(no_count + sql)
result = cursor.fetchone()
# Check if primary key is set and if there are no errors:
if result[0] > 1 and result[1] == '':
# Commit SP
cursor.execute('COMMIT')
return result[0]
There is a mapping for creating the models, because the MS-SQL
database expect different data then the normal objects, like ‘order’.
def adding_data_into_vadain(self, order):
for curtain in order.curtains.all():
order_id = WaOrders.export(
type=format(curtain.type)
)
# relation with default and vadain db.
order.exported_id = order_id
order.save()
The function is working proper by running the program, but by running ‘manage.py test’ will be created a test databases. This is given the following problems:
By creating test database is missing the south tables (this is also not needed in the legacy database)
By changing the SOUTH_TESTS_MIGRATE to False I’m getting the error message that the tables are already exists of the default database.
My test is as follow:
class AddDataServiceTest(TestCase):
fixtures = ['order']
def test_data_service(self):
# add data into vadain_import data
for order in Order.objects.all():
AddingDataService.adding_data_into_vadain(order)
# test the exported values
for order in Order.objects.all():
exported_order = WaOrders.objects.get(order_exported_id=order.exported_id)
self.assertEqual(exported_order.type, 'Pleat curtain')
Can somebody advise me how I can test the situation?
maybe inside your WaOrders you can extend save() method and call there export function.

Categories