Why Django raw query is not working - django

Good people,
I have installed djangoratings in my django project and i want to select records directly using raw sql from the djangoratings tables, i have followed the instruction given here but nothing seems to work.
My code looks like this;
def InsertRecord():
from django.db import connection, transaction
cursor = connection.cursor()
cursor.execute(" Select ip_address from djangoratings_vote where id=%d ",[3])
row = cursor.fetchone()
print row # row has None at this point
The function does not select the row, despite it exists in the table.
Am using , django 1.2.1, sqlite3
What am i not doing?
gath

I think only strings will work, so replace %d with %s and it should work
cursor.execute(" Select ip_address from djangoratings_vote where id=%s ",[3,])

good people,
Sorry i saw where the mistake was,
On the sql string, the formating place holder should be "%s" and not "%d"
thanks

Related

Django ORM can't execute it's own raw query [duplicate]

You can print a queryset's SQL as follows:
print str(queryset.query)
however, for some reason this removes quotation marks, so you get:
SELECT `tableA`.`fieldA` FROM `fieldA` WHERE `tableA`.`fieldB` = Foo
instead of:
SELECT `tableA`.`fieldA` FROM `fieldA` WHERE `tableA`.`fieldB` = "Foo"
notice the missing ""
How can this be corrected?
If the underlying database is PostgreSQL you can do:
from django.db import connection
sql, params = queryset.query.sql_with_params()
cursor = connection.cursor()
cursor.mogrify(sql, params)
sql_with_params returns the plain query without any values substituted and the parameters that will be inserted in the query.
It is still not recommended to use .mogrify() for other purposes than debugging because the method may disappear in the future.
If you want to execute the query, you can/should just use .raw().
YourModel.objects.raw(sql, params)
not quite what you want, but if you have DEBUG = True you can use
from django.db import connection
connection.queries
update:
looking at the Queryset __str__ method:
__str__(self)
| Returns the query as a string of SQL with the parameter values
| substituted in.
|
| Parameter values won't necessarily be quoted correctly, since that is
| done by the database interface at execution time.
If this is for debug purpose you should look into django-debug-toolbar that will show you all queries ran for any view you're looking at

Fetch table data from database without a model related to it

Im looking for a way to fetch some data to display to the user.(Run a raw sql query like)
select * from "DB-table" where Name like "%blabla%" and Year like "%2020%"
My problem is that the "DB-table" lives in my database but its already populated with important data which is not related to some model in my django-app. Its a standalone table with a lot of data.
How can i refer to that table from my views.py file?
Clearly my question was not so hard..But as im new to django and python i overcomplicated things. I managed to fetch the data i wanted using something like
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM 'Nvd-data'")
res = cursor.fetchall()
print(res)
For more advanced queries i think django documentation is fine.Hope that silly question helps someone

Bulk delete Django by ids

I writing a project using Django REST Framework, Django and Postgres as a database. I want to bulk delete in one query. So, it is possible to do without writing a query using pure SQL?
There is an example, but the count of executet query equal length of a list of ids (for example, if in delete_ids 2 ids, Django will execute 2 queries):
delete_ids = [...]
MyModel.objects.filter(id__in=delete_ids).delete()
Not possible using the filter and delete together using raw sql query.
https://docs.djangoproject.com/en/2.1/topics/db/sql/
MyModel.objects.raw('DELETE FROM my_model WHERE id IN (%s)', [','.join([list_of_ids])])
For fast deletes won't advice but you can also use
sql.DeleteQuery(MyModel).delete_qs(qs, using=qs.db)
jackotyne's answer is incorrect as a DELETE statement cannot be run with django raw. The idea behind django raw is that it returns a queryset, but DELETE won't do that.
Please read the reply to this answer.
You will need a database cursor as stated in the django documentation.
with connection.cursor() as cursor:
cursor.execute(
'DELETE FROM "appname_modelname" WHERE id IN (%s)' % ', '.join(delete_ids)
)
Of course it is better to filter with django and get a queryset and do a bulk delete with queryset.delete(), but that is not always possible depending on the data's logic.

Poor performance of Django ORM with Oracle

I am building a Django website with an Oracle backend, and I observe very slow performance even when doing simple lookups on the primary key. The same code works very fast when the same data are loaded in MySQL.
What could be the reason for the poor performance? I have a suspicion that the problem is related to the use of Oracle bind parameters, but this may not be the case.
Django model (a test table with ~6,200,000 rows)
from django.db import models
class Mytable(models.Model):
upi = models.CharField(primary_key=True, max_length=13)
class Meta:
db_table = 'mytable'
Django ORM (takes ~ 1s)
from myapp.models import *
r = Mytable.objects.get(upi='xxxxxxxxxxxxx')
Raw query with bind parameters (takes ~ 1s)
cursor.execute("SELECT * FROM mytable WHERE upi = %s", ['xxxxxxxxxxxxx'])
row = cursor.fetchone()
print row
Raw query with no bind parameters (instantaneous)
cursor.execute("SELECT * FROM mytable WHERE upi = 'xxxxxxxxxxxxx'")
row = cursor.fetchone()
print row
My environment
Python 2.6.6
Django 1.5.4
cx-Oracle 5.1.2
Oracle 11g
When connecting to the Oracle database I specify:
'OPTIONS': {
'threaded': True,
}
Any help will be greatly appreciated.
[Update]
I did some further testing using the debugsqlshell tool from the Django debug toolbar.
# takes ~1s
>>>Mytable.objects.get(upi='xxxxxxxxxxxxx')
SELECT "Mytable"."UPI"
FROM "Mytable"
WHERE "Mytable"."UPI" = :arg0 [2.70ms]
This suggests that Django uses the Oracle bind parameters, and the query itself is very fast, but creating the corresponding Python object takes a very long time.
Just to confirm, I ran the same query using cx_Oracle (note that the cursor in my original question is the Django cursor).
import cx_Oracle
db= cx_Oracle.connect('connection_string')
cursor = db.cursor()
# instantaneous
cursor.execute('SELECT * from mytable where upi = :upi', {'upi':'xxxxxxxxxxxxx'})
cursor.fetchall()
What could be slowing down Django ORM?
[Update 2] We looked at the database performance from the Oracle side, and it turns out that the index is not used when the query comes from Django. Any ideas why this might be the case?
Using TO_CHAR(character) should solve the performance issue:
cursor.execute("SELECT * FROM mytable WHERE upi = TO_CHAR(%s)", ['xxxxxxxxxxxxx'])
After working with our DBAs, it turned out that for some reason the Django get(upi='xxxxxxxxxxxx') queries didn't use the database index.
When the same query was rewritten using filter(upi='xxxxxxxxxxxx')[:1].get(), the query was fast.
The get query was fast only with integer primary keys (it was string in the original question).
FINAL SOLUTION
create index index_name on Mytable(SYS_OP_C2C(upi));
There seems to be some mismatch between the character sets used by cx_Oracle and Oracle. Adding the C2C index fixes the problem.
UPDATE:
Also, switching to NVARCHAR2 from VARCHAR2 in Oracle has the same effect and can be used instead of the functional index.
Here are some useful discussion threads that helped me:
http://comments.gmane.org/gmane.comp.python.db.cx-oracle/3049
http://comments.gmane.org/gmane.comp.python.db.cx-oracle/2940

Create or copy table dynamically, using Django db API

how can I perform smth like
CREATE TABLE table_b AS SELECT * FROM table_a
using Django db API?
As an alternative you could potentially leverage South since it has an API for creating and dropping tables.
http://south.aeracode.org/wiki/db.create_table
I haven't tried this outside the context of a migration so no guarantees it will work out-of-the-box.
Django's ORM isn't intended for things like this. I would suggest you're doing something the wrong way but you haven't explained why you want to do this, so I can't really comment.
Anyway. You can use Django's raw SQL:
def my_custom_sql():
from django.db import connection, transaction
cursor = connection.cursor()
# Data modifying operation - commit required
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
transaction.commit_unless_managed()
# Data retrieval operation - no commit required
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
http://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly
You can't. You'll have to drop to DB-API.