emmett-framework / emmett

The web framework for inventors
Other
1.03k stars 70 forks source link

compute does not work with emmett relations #358

Closed Triquetra closed 2 years ago

Triquetra commented 3 years ago

With this table definition (I can post the complete sample code if it would be helpful):

class Tmodel(Model):
    has_many('tas', {'amodels': {'via': 'tas'}})
    has_many('tbs', {'bmodels': {'via': 'tbs'}})

    a = Field()
    # total_avg_cost = Field.decimal(10, 2, auto_validation=False)

    @rowmethod('total_avg_cost')
    def get_avg_cost(self, row):
        avg_list = [lst.my_avg() for lst in row.bmodels.select(db.Tb.ALL) if lst.my_avg()]
        return sum(avg_list) / len(avg_list) if avg_list else 0

Tmodel.first().total_avg_cost() works as a rowmethod (returns 0 when no related records).

But when using @compute instead, Tmodel.create(a='foo') fails to create the record, with an 'Invalid Value' error.

If setting auto_validation=False on the total_avg_cost field, the record is created with total_avg_cost=None instead of the computed 0 (when there are no related records).

gi0baro commented 3 years ago

@Triquetra so, I admit I wrote unclear documentation about this, or at least this is an unexpected behaviour caused by pyDAL actually.

The reality is that while rowattr and rowmethod actually receive the real row instance, the compute receive an OpRow object, since the computation logic is still handled by pyDAL library through this method, and consequentially you don't have access to relations' attributes, like row.bmodels.

So my answer to this is: I should quickly fix the documentation specifying the difference, and then probably re-engineer the computation logic overriding the one by pyDAL to use Emmett ORM objects. The re-engineering will obviously take a while.

gi0baro commented 3 years ago

@Triquetra side note: this is true also for callbacks accepting existing records, like before_update, but probably the documentation is better there since the parameter is named fields instead of row.

gi0baro commented 3 years ago

Partially related: #174, #197

Triquetra commented 3 years ago

Thank you for the clarification. At least now I know I'm not crazy (well, at least not for that reason)! Thank you also for all of your hard work on emmett.