Open and3rson opened 2 years ago
Transaction is a subclass of batch.WriteBatch, which implements the context manager interface, so I believe this functionality should already exist. Let me know if there's something it's missing though
I tried following code, but got error: ValueError: Transaction not in progress, cannot be used in API requests.
db = firestore.Client(project="project_1", database="db_1")
doc_ref = db.collection('docs').document('doc1')
with db.transaction() as t:
snapshot = doc_ref.get(transaction=t)
t.update(doc_ref, {"a": 2})
Sorry, you are right, firestore's transactions don't work well with context managers. I definitely see this as something that should be addressed. It's especially confusing since it can be used as a context manager, but the transaction isn't initiated when used that way
We're currently re-evaluating how retries are handled in Transactions (and other places). I can try to address this gap as a part of that project
Hi @daniel-sanche Is there any update? Thx.
Is your feature request related to a problem? Please describe. Currently, transactions are only supported via
@firestore.transactional
, and the motivation is clear: to allowfirestore.Client
to re-run the entire transaction when contention occurs.However, a widely used (and very much Pythonic) pattern for working with transactional entities is by using context managers: DB clients, files, streams - they all implement context manager protocol.
firestore.Client
, on the other hand, requires the developer to create boilerplate functions for every transaction, even in cases when retries are unwanted.Furthermore,
google.cloud.firestore_v1.services.firestore.FirestoreClient
already implements the context manager protocol.Describe the solution you'd like I'd like
firestore.Client
to implement a context manager as such:Of course, contrary to the current suggested usage with
@firestore.transactional
, it's clear that the context manager approach will not support retries, since the code is only evaluated once. But this is a totally expected behavior that can be documented in the class docstring itself for more transparency.Describe alternatives you've considered
google.cloud.firestore_v1.services.firestore.FirestoreClient
to achieve this, but my initial goal was to have fewer wrappers, and the latter introduces even more verbosity, which is the opposite of what I was looking for.I've been tempted to use
firestore.Transaction
directly, but most of its interesting methods are private, so I decided to avoid relying on an internal API that might change in future. Here's what it might have looked like: