Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#34168 closed New feature (wontfix)

Add support for list of parameters to the QuerySet.raw().

Reported by: Marek Rouchal Owned by: nobody
Component: Database layer (models, ORM) Version: 4.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Django's .raw() function already has the params=[] argument to inject properly quoted strings - but what if I need to inject a list (of strings or numbers), like in:

WHERE item.color IN ('red', 'green', 'blue'). # %s being: ['red', 'green', 'blue']

Proposal is to allow lists and tuples in the params argument, which are then rendered as: "( <quoted-element-1>, <quoted-element-2>, ...)", using the existing quoting algorithm, applied to each list element.

Change History (2)

comment:1 by Mariusz Felisiak, 2 years ago

Resolution: wontfix
Status: newclosed
Summary: add proper quoting for lists in raw SQL queriesAdd support for list of parameters to the QuerySet.raw().

Thanks for this ticket. It already works on PostgreSQL and MySQL (however unintentionally) when passing list of tuples, e.g.

query = "SELECT * FROM raw_query_author WHERE first_name in %s"
params = [("Bill", "Jill")]
Author.objects.raw(query, params=params)

We don't really want to encourage users to use raw() anymore since almost everything is covered by the ORM, so adding a new feature to raw queries is always a bit controversial.
Please first start a discussion on the DevelopersMailingList, where you'll reach a wider audience, and follow the guidelines with regards to requesting features. Initially "wontfix" from me.

comment:2 by Marek Rouchal, 2 years ago

The specific problem I am facing is that I need to access an existing database whose schema I cannot alter; I used the Django tool to extract the tables to create models.py, which worked great, and I already hacked the model definitions, e.g. to replace a simple IntegerField with a ForeignKey. But there are specific tables, where there is an IntegerField which may contain a ForeignKey from more than one table (think of a group and a user table; whether it is a user or a group, is defined by another column):

class Permission(models.Model):
    ...
    user_or_group_id = models.IntegerField(db_column='user_or_group_id', blank=True, null=True)
    is_group = models.IntegerField(db_column='is_group', blank=True, null=True)

So what I would need here is something like a union on ForeignKey (coming from either a User or a Group table).
So I used raw SQL for the required joins; I have not been able to formulate a Django queryset to join on a field which is not modeled with ForeignKey.
That is why I was asking for some better support of raw SQL...

Last edited 2 years ago by Marek Rouchal (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top