- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试在我的数据库框架中管理事务(我使用 MongoDB 和 umongo 而不是 pymongo)。
要使用事务,必须沿整个调用链传递一个session
kwarg。我想提供一个上下文管理器来隔离事务。只有调用链末尾的函数需要了解 session
对象。
我发现了上下文变量,并且我已经接近一些东西,但还没有完全实现。
我想要什么:
with Transaction():
# Do stuff
d = MyDocument.find_one()
d.attr = 12
d.commit()
这是我现在想到的:
s = ContextVar('session', default=None)
class Transaction(AbstractContextManager):
def __init__(self):
self.ctx = copy_context()
# Create a new DB session
session = db.create_session()
# Set session in context
self.ctx.run(s.set, session)
def __exit__(self, *args, **kwargs):
pass
# Adding a run method for convenience
def run(self, func, *args, **kwargs):
self.ctx.run(func, *args, **kwargs)
def func():
d = MyDocument.find_one()
d.attr = 12
d.commit()
with Transaction() as t:
t.run(func)
但是我没有很好的上下文管理器语法。上下文管理器的要点是“其中的所有内容都应该在该上下文中运行”。
我上面写的并不比仅仅使用函数更好:
def run_transaction(func, *args, **kwargs):
ctx = copy_context()
session = 12
ctx.run(s.set, session)
ctx.run(func)
run_transaction(func)
我是不是走错了路?
我是否滥用了上下文变量?
还有其他方法可以实现我想要做的事情吗?
<小时/>基本上,我希望能够像上下文管理器一样打开上下文
session = ContextVar('session', default=None)
with copy_context() as ctx:
session = db.create_session()
# Do stuff
d = MyDocument.find_one()
d.attr = 12
d.commit()
我将其嵌入到 Transaction
上下文管理器中来管理 session 内容,并且仅在用户代码中保留对 d
的操作。
最佳答案
您可以使用上下文管理器来创建 session 和事务,并将 session 存储在 ContextVar 中以供其他函数使用。
from contextlib import contextmanager
from contextvars import ContextVar
import argparse
import pymongo
SESSION = ContextVar("session", default=None)
@contextmanager
def transaction(client):
with client.start_session() as session:
with session.start_transaction():
t = SESSION.set(session)
try:
yield
finally:
SESSION.reset(t)
def insert1(client):
client.test.txtest1.insert_one({"data": "insert1"}, session=SESSION.get())
def insert2(client):
client.test.txtest2.insert_one({"data": "insert2"}, session=SESSION.get())
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--url", default="mongodb://localhost:27017")
args = parser.parse_args()
client = pymongo.MongoClient(args.url)
# Create and lear collections, collections must be created outside the transaction
insert1(client)
client.test.txtest1.delete_many({})
insert2(client)
client.test.txtest2.delete_many({})
with transaction(client):
insert1(client)
insert2(client)
for doc in client.test.txtest1.find({}):
print(doc)
for doc in client.test.txtest2.find({}):
print(doc)
if __name__ == "__main__":
main()
关于python - 为 contextvars.Context 提供 ContextManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59264158/
将字典设置为 ContextVar 默认值: var: ContextVar[dict] = ContextVar('var', default={}) ...有点管用,因为字典将默认可用,但它总是引
我对 asyncio 和 ContextVars 完全陌生,我刚刚阅读了 3.7 中的新功能并发现了 ContextVars,我很难理解它的用法,我知道它很有用在协程中,而不是使用 thread.lo
如果我在异步网络服务器中有一个结构,例如 import contextvars ... my_context_var = contextvars.ContextVar("var") @app.rout
就目前而言,我已经找到了很多有关 contextvars 模块如何与 asyncio 配合使用的示例,但没有找到有关如何与线程配合使用的示例(asyncio.get_event_loop().run_
我正在尝试在我的数据库框架中管理事务(我使用 MongoDB 和 umongo 而不是 pymongo)。 要使用事务,必须沿整个调用链传递一个session kwarg。我想提供一个上下文管理器来隔
这个问题已经有答案了: How to update global variable in asyncio create_task (2 个回答) 已关闭 3 年前。 我当前有两个无限异步任务正在运行,
我正在使用 Django 2.2 和 Python 3.7 构建单个数据库/共享架构 Multi-Tenancy 应用程序。 我正在尝试使用新的 contextvars API 在 View 之间共享
Python的thread-local data和 ContextVar s 似乎实现了相同的目标(虽然 API 略有不同),唯一面向用户的区别是 ContextVar s 使用异步代码(协程和 as
我是一名优秀的程序员,十分优秀!