• Saturday

    • SBSC. Continued on the model/schema redesigns.
    • session.refresh(var) if you’ve committed changes that affect it (like for aggregators/observers).
    • sqlalchemy_utils.observes appears to be smart enough to NOT trigger directly on the objects/vars/paths you pass to the decorator, but rather the nested cols you actually use within the function. This is good in 1 way: You can observe the high level, and it will only trigger on changes to the lowest dep (not ANY change to the highest obj tree). This is bad in 1 way: A bit misleading, when you think that the value you pass to the observer explicitly defines the trigger scope.
    • Actually I’m not sure about the above^. When I had observes(game), changing game.line triggered both opponents to update, but changing game.opponents[0].score only triggered opponent[0] to update. Overall, I just want to be explicit about what triggers the observer calc.
    • You CAN have tables FK to themselves (and be self-referential in sqla): https://docs.sqlalchemy.org/en/20/orm/self_referential.html. This is common for adjacency matrixes, where a Node table might have a parent/child Node.
    • Renamed Opponent table to Contestant to avoid confusion.
    • Important: Looks like sqlalchemy_utils.observes can observe cols of the local table, as well as relationships. But for relationships, it seems to ONLY support aggregation functions. Example: you have a one-to-many relationship. The observer can do a nested calc like child_count = len(parent.children). But it CANNOT do something like first_child_plus_decade = parent.children[0].age + 10 and trigger on the children[0].age change. Unfortunately, that’s exactly what I need for Contestant.score (for the opponent).
    • To fix this, I just denormalized opponent_score into every row of the Contestant table.
    • Ended up keeping the change to switch the order of Game and Contestant in the hierarchy. Keeps the purity (standardization) of the many-to-one relationship and removes the hardcoded 1s and 2s. Gonna have some circular referencing in the bidirectional relationship between them, no matter which wraps which. And could have made Pick only FK to Contestant no matter what, since they’re bidirectionally related, but kept that change as well. Pick -> Contestant -> Game. No need for Pick FKs to both.