Code

Opened 6 years ago

Closed 18 months ago

#9049 closed New feature (wontfix)

queryset .extra(tables=[...]) unnecessarily quotes table names

Reported by: tobias Owned by: nobody
Component: Database layer (models, ORM) Version: 1.0
Severity: Normal Keywords:
Cc: elsdoerfer@…, sciyoshi@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

A while back I could happily pass subqueries, joins, and even pl/pgsql calls in through the queryset .extra() method, via the tables parameter. Sometime in the past few months that changed, when Django began quoting the "table names" i passed it.

Why does Django need to do this? I can quote the table names myself if I know them to need such treatment--and not doing it by default opens up a lot of possibilities for the .extra method and Django ORM in general.

Alternatively, to avoid breaking existing code, we could add an option to .extra that told it not to quote table names.

Thanks.

Attachments (1)

dont_quote_extra_tables.patch (599 bytes) - added by tobias 6 years ago.

Download all attachments as: .zip

Change History (9)

Changed 6 years ago by tobias

comment:1 Changed 6 years ago by mtredinnick

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

This patch isn't going in, it will cause too many difficult-to-diagnose bugs in people's code to support something that only worked by accident.

There's a case for adding a literal-pass-through class to a few places in the query code that can be used to avoid any quoting or further processing and I've played around with that a bit in code with clients already. It mostly works (right now, the way to get what you want is to subclass Query and override the get_from_clause method). I'm also thinking about how to add general support for nested subqueries in the FROM-clause portion of the query which will help here. With a good tail-wind, that's likely to be ready for 1.1.

Django's ORM isn't meant to be a total replacement for SQL and this is one of those places where you probably can't just use the normal function calls right now. Subclassing and overriding the appropriate methods still works, however.

I'll leave this open as the reference point for adding subqueries and literals to "FROM".

comment:2 Changed 6 years ago by tobias

Looks like there's already a partial solution to this in #7231, though having 'tables', 'join', and potentially 'subquery' keyword arguments to .extra() might raise unnecessary confusion when they all do virtually the same thing.

comment:3 Changed 6 years ago by miracle2k

  • Cc elsdoerfer@… added

comment:4 Changed 6 years ago by sciyoshi

  • Cc sciyoshi@… added

See also #7907

comment:5 Changed 3 years ago by lukeplant

  • Severity set to Normal
  • Type set to New feature

comment:6 Changed 2 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:7 Changed 2 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:8 Changed 18 months ago by akaariai

  • Resolution set to wontfix
  • Status changed from new to closed

Seems like no action in 4 years for a reference point ticket is a good reason for closing.

It would be nice to have an easy way to inject subqueries into ORM queries, but .extra() I don't think we want to push .extra() in that direction.

Maybe we would want to add a generic "mark_safe" style way to avoid quoting of names. This would be useful for example in:

class SomeView(models.Model):
    cols...

    class Meta:
        db_table = mark_safe("(select * from sometable join othertable)")
        managed = False

Suddenly, you have inlined view! Would also solve this ticket's issue.

But, not this ticket's issue.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.