Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Using named parameters on a raw SQL query

I'm trying to execute a raw query that is build dynamically. To assure that the parameters are inserted on the valid position I'm using named parameters.

This seem to work for Sqlite without any problems. (all my tests succeed) But when I'm running the same code against MariaDb it fails..

A simple example query:

 SELECT u.* 
    FROM users_gigyauser AS u
  WHERE u.email like :u_email
    GROUP BY u.id
    ORDER BY u.last_login DESC
  LIMIT 60 OFFSET 0

Parameters are:

 {'u_email': '%test%'}

The error I get is a default syntax error as the parameter is not replaced. I tried using '%' as a indicator, but this resulted in sql trying to parse

%u[_email]

and that returned a type error.

I'm executing the query like:

 raw_queryset = GigyaUser.objects.raw(self.sql_fetch, self._query_object['params'])

Or when counting:

 cursor.execute(self.sql_count, self._query_object['params'])

Both give the same error on MariaDB but work on Sqlite (using the ':' indicator)

Now what am I missing?

like image 424
Flip Vernooij Avatar asked Mar 30 '16 14:03

Flip Vernooij


People also ask

Should you use raw SQL in Django?

I would balance that by cautioning against overuse of the raw() and extra() methods.” Django project co-leader Jacob Kaplan-Moss says (paraphrased): “If it's easier to write a query using SQL than Django, then do it. extra() is nasty and should be avoided; raw() is great and should be used where appropriate.”

Can we use SQL query in Django?

Django gives you two ways of performing raw SQL queries: you can use Manager. raw() to perform raw queries and return model instances, or you can avoid the model layer entirely and execute custom SQL directly. Explore the ORM before using raw SQL!

Does Django ORM support subquery?

¶ Django allows using SQL subqueries.

How does Django's ORM protect against SQL injection?

Within that layer, Django protects itself from SQL injection by using query parameterization. Within the ORM layer, Django defines SQL queries separated from the query's parameters, and the database driver is in charge of escaping each of the parameters.


2 Answers

edit:

The format needs to have s suffix as following:

%(u_email)s
like image 186
yedpodtrzitko Avatar answered Oct 31 '22 14:10

yedpodtrzitko


If you are using SQLite3, for some reason syntax %(name)s will not work. You have to use :name syntax instead if you want to pass your params as {"name":"value"} dictionary.

It's contrary to the documentation, that states the first syntax should work with all DB engines.

Heres the source of the issue: https://code.djangoproject.com/ticket/10070#comment:18

like image 1
Jack Scandall Avatar answered Oct 31 '22 15:10

Jack Scandall