Hello folks!
I have a complex queryset here that do joins in at least 8 tables. The query is fast, but has use of Postgresql `concat` method, and to make it have correct aliases I'm using `qs.query.alias_map` where qs is my queryset instance:
def my_complex_queryset(self):
qs = self.filter(*lot_of_stuff_with_lot_of_joins)
alias_map = {
j.table_name: a for a, j in qs.query.alias_map.items()
if j.table_name in ['table_a', 'table_b']
}
concat_str = (
'concat("{table_a}"."city", "{table_a}"."state") '
'!= concat("{table_b}"."city", "{table_b}"."state")'
).format(
table_a=alias_map['table_a'],
table_b=alias_map['table_b']
)
qs = qs.extra(where=[concat_str])
return qs
The problem is when the query is re-executed with some other table in the joins because it will change the alias_map but won't run my method again to update the concat_str:
my_qs = MyModel.objects.my_complex_queryset()
print my_qs
# now it will fail because alias changed:
print my_qs.filter(another_table_1__another_table_2__id__in=[1, 2, 3])
The error I receive is:
ProgrammingError: invalid reference to FROM-clause entry for table "table_a"
LINE 1: ... AND U0."some_id" IN (13361, 9820) AND (concat("table_a...
^
HINT: Perhaps you meant to reference the table alias "u9".
The great question is: Is possible to do the query with dynamic aliases to be used in concat string? Maybe the `tables` argument to extra? I not saw much doc about it :\.
My Django version is 1.6.x, not because my choice but because software here still a bit legacy about Django versions and we won't change until January.
Thanks for your attention!