我需要获取以下模型字段的列表:
@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()
答案 0 :(得分:0)
这是this answer作者的this library的副本/粘贴:
据我所知,当您尝试使用时会引发此异常 懒客户端,而没有正确初始化它们。任何懒惰的 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)
作为示例,您可以查看Auth/Auth microservice代码,其中 定义的文档和与实际存储在不同的文件中 用法。另外,这些文件以代码为例(documents.py和 prepare_mongodb.py)将帮助您找到解决方案。
答案 1 :(得分:0)
诀窍是
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)