|
|
|
|
|
by zzzeek
4535 days ago
|
|
not in that case. if the code wanted to do this decrement on the SQL side it would have to be: purchase.downloads_left = Purchase.downloads_left - 1
which would emit on the next flush. in this code specifically, using that approach it would have to call session.flush() and then re-query for that value since it wants to check what the database came up with. So in that sense it would be better just to emit an explicit UPDATE..RETURNING, which is easy to do with SQLA; this is an example of how "dropping down" a level of abstraction is a critical feature with SQL abstraction tools.however, this is only one way to do it, which is the so-called pessimistic approach. An optimistic approach would just ensure that the transaction isolation is in repeatable read, so that the flush (occurs within the commit() here) would just fail in the very unlikely case a single user is submitting twice. SQLAlchemy also offers a "version counter" feature that can accomplish the same task if RR isn't an option. Both of these are configuration-level features that would allow the code to remain unchanged. The "session.add(purchase)" is also unnecessary in that code sample, and the code also has a bug in that it does not commit the transaction when downloads_left reaches zero, so the number can never actually reach zero in the database. |
|