无法获取模型字段列表
Can't get list of model fields
我需要获取模型字段列表,例如:
@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'
]
所以,我有 returns 字段列表
的功能
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()
这是 this answer from the author of this library 的 copy/paste:
As far as I remeber, this exception raises when you're trying to use
lazy clients without initializing them properly. Any lazy class of
uMongo expects that the used database will be specified before the
usage. Everything that you need is to specify the used database and
invoke the init method of your lazy instance, like this:
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)
As an example you can look into Auth/Auth microservice code, where
documents defined and store in the separate files from the actual
usage. Also these files with code as examples (documents.py and
prepare_mongodb.py) will help you to find a solution.
诀窍在于
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)
我需要获取模型字段列表,例如:
@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'
]
所以,我有 returns 字段列表
的功能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()
这是 this answer from the author of this library 的 copy/paste:
As far as I remeber, this exception raises when you're trying to use lazy clients without initializing them properly. Any lazy class of uMongo expects that the used database will be specified before the usage. Everything that you need is to specify the used database and invoke the init method of your lazy instance, like this:
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)
As an example you can look into Auth/Auth microservice code, where documents defined and store in the separate files from the actual usage. Also these files with code as examples (documents.py and prepare_mongodb.py) will help you to find a solution.
诀窍在于
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)