【问题标题】:Can't get list of model fields无法获取模型字段列表
【发布时间】:2019-12-04 21:33:51
【问题描述】:

我需要获取模型字段列表,例如:

@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()

【问题讨论】:

    标签: python mongodb umongo


    【解决方案1】:

    诀窍在于

    properties=get_class_properties(Todo)

    早于

    调用

    async def mongo_client(app):

    解决方案是以正确的顺序使用事物(参见 cmets 代码)

    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)
    

    【讨论】:

      【解决方案2】:

      这是this library的作者对this answer的复制/粘贴:

      据我所知,当您尝试使用时会引发此异常 懒惰的客户端没有正确初始化它们。任何懒惰类 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.pyprepare_mongodb.py) 将帮助您找到解决方案。

      【讨论】:

        猜你喜欢
        • 2011-03-07
        • 2018-12-14
        • 2016-09-30
        • 1970-01-01
        • 2022-01-02
        • 2019-08-09
        • 1970-01-01
        • 2014-05-09
        • 1970-01-01
        相关资源
        最近更新 更多