>我需要获取模型字段列表,例如:
@instance.register
class Todo(Document):
title = fields.StringField(required=True, default='Name')
description = fields.StringField()
created_at = fields.DateTimeField()
created_by = fields.StringField()
priority = fields.IntegerField()
自
[
'title',
'description',
'created_at',
'created_by',
'priority'
]
所以,我有返回字段列表的函数
def get_class_properties(cls):
attributes = inspect.getmembers(cls, lambda a: not (inspect.isroutine(a)))
return [attr for attr in attributes if not (attr[0].startswith('__') and attr[0].endswith('__'))][1]
但是用法给了我这个错误 umongo.exceptions.NoDBDefinedError: init must be called to define a db
用法: properties=get_class_properties(Todo)
UPD这是我的 mongo 初始化代码:
async def mongo_client(app):
conf = app["config"]["mongo"]
client = AsyncIOMotorClient(host=conf["host"], port=conf["port"])
db = client[conf["db"]]
instance.init(db)
await Todo.ensure_indexes()
app["db_client"]: AsyncIOMotorClient = client
app["db"] = db
yield
await app["db_client"].close()
这是该库作者对这个答案的复制/粘贴:
据我所知,当您尝试使用 没有正确初始化它们的惰性客户端。任何懒惰类 uMongo 期望在 用法。您所需要的只是指定使用的数据库和 调用惰性实例的 init 方法,如下所示:
from motor.motor_asyncio import AsyncIOMotorClient from umongo import MotorAsyncIOInstance client = AsyncIOMotorClient("mongodb://user:password@host:port/") client = client["test_database"] lazy_umongo = MotorAsyncIOInstance() lazy_umongo.init(client)
例如,您可以查看身份验证/身份验证微服务代码,其中 文档定义并存储在与实际文件分开的文件中 用法。还有这些文件以代码作为示例(documents.py 和 prepare_mongodb.py(将帮助您找到解决方案。
是
properties=get_class_properties(Todo)
早于
async def mongo_client(app):
解决方案是以正确的顺序使用事物(请参阅代码注释(
async def init_app(argv=None):
app = web.Application(middlewares=[deserializer_middleware], logger=logger)
app["config"] = config
conf = app["config"]["mongo"]
client = AsyncIOMotorClient(host=conf["host"], port=conf["port"])
db = client[conf["db"]]
instance.init(db)
# Remove this line:
# app.cleanup_ctx.append(mongo_client)
app.cleanup_ctx.append(api_client)
register_routes(app)
return app
def register_routes(app: web.Application):
# Use here:
todo_resource = RestResource(
entity='todo',
factory=Todo,
properties=get_class_properties(Todo)
)
todo_resource.register(app.router)