Opened 4 years ago

Closed 4 years ago

Last modified 4 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, 4 years ago

Resolution: → wontfix
Status: new → closed
Summary: add proper quoting for lists in raw SQL queries → Add 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, 4 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 4 years ago by Marek Rouchal (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top