W1ldPo1nter / django-queryable-properties

Write Django model properties that can be used in database queries.
BSD 3-Clause "New" or "Revised" License
72 stars 1 forks source link

AnnotationProperty does not appear in select clause of raw SQL #3

Closed tdisbm closed 3 years ago

tdisbm commented 3 years ago

Given this model

class MyModel(Model):
    f1 = CharField()
    f2 = AnnotationProperty(
        annotation=RegexpMatches(source='f1', regexp=MY_REGEXP, group=1)
    )

    objects = QueryablePropertiesManager()

I'm trying to apply filter MyModel.objects.filter(f2='a').first() and it results in postgres error for a reason. After some researches i found that f2 are not included in select clause of raw (generated) sql. Generated SQL looks like:

SELECT "myapp_mymodel"."f1"
FROM   "myapp_mymodel"
WHERE  (regexp_matches("myapp_mymodel"."f1", (^m.+)_.+))[1] = 'a'

And my question is: Is it possible to include annotated fields in select clause with an alias?

W1ldPo1nter commented 3 years ago

Hi,

I'm guessing RegexpMatches is some kind of custom expression? If that's the case, then it's hard for me to replicate the problem without its implementation.

But from what I can see, the behavior is exactly as intended: you use the property in a filter only, which is why django-queryable-properties only adds it to the WHERE clause for performance reasons (each selected column makes the query more expensive). If you want to actually SELECT the column represented by the property, you have to explicitly call select_properties (see Selecting annotations). In your case, that would be MyModel.objects.select_properties('f2').

As an aside (since I don't know what exactly you're going to be using the property for): Using an AnnotationProperty for sth. like this, which only performs a regex operation, may not be optimal since the property's regular getter (when accessing it on an individual MyModel object via my_obj.f2) will also execute a query as described here. You can ignore this if you don't plan to use the getter individually.

Let me know if this helps or if there are further issues.

W1ldPo1nter commented 3 years ago

Closing this due to inactivity.