coleifer / peewee

a small, expressive orm -- supports postgresql, mysql, sqlite and cockroachdb
http://docs.peewee-orm.com/
MIT License
11.06k stars 1.37k forks source link

Is it possible to cache a field? #2881

Closed stenci closed 4 months ago

stenci commented 4 months ago

Hi All,

Is it possible to prevent the following code from executing the same query twice when iterating self.cnc_program_sheets when calling both quantity_used and comments?

# model definition
class CncProgramSheet(PeeweeModel):
    inventory_sheet = peewee.ForeignKeyField(InventorySheet, backref='cnc_program_sheets')

# inside InventorySheet
    @property
    def quantity_used(self):
        return sum(1 for s in self.cnc_program_sheets if s.n_parts_already_cut)

    @property
    def comments(self):
        return '\n'.join(s.comment for s in self.cnc_program_sheets)

I have enabled the SQL logging (with the code below), and I see that peewee executes the same query when both quantity_used and comments are called. I have added caching to my properties, so if they are called more than once they are not calculated again, and I would like to know if peewee allows to enable a similar caching to its native fields.

I can create a third cnc_program_sheets2 property with my own cache, but I don't want to reinvent the wheel if peewee already comes with it.

I was surprised to see the double execution, because I assumed the caching was automatic, as mentioned here, but perhaps that's a different context.

if log_sqlite_queries:
    logger = logging.getLogger('peewee')
    logger.setLevel(logging.DEBUG)
    logger.addHandler(logging.StreamHandler())
coleifer commented 4 months ago

Foreign-key iterations are not cached. My suggestion would be to implement your own caching if you intend to iterate over the foreign-key's back reference set more than once.