如何在Python中以类属性形式访问字段构建MongoDB查询条件?
解决方案
方法一:利用attrs字段元数据自动生成类属性
通过attrs的field元数据标记字段路径,在类加载时自动生成对应的类级属性,返回MongoDB查询所需的字符串路径:
from attrs import define, field @define(slots=True) class User: @define() class UserDetails: status: UserStatus = field(default=UserStatus.ALIVE, metadata={"path": "status"}) address: str = field(default=None, metadata={"path": "address"}) user_id: CustomTypeId = field(default=None, metadata={"path": "user_id"}) details: UserDetails = field(factory=UserDetails, metadata={"path": "details"}) @classmethod def __init_subclass__(cls): # 处理当前类的字段映射 for attr in cls.__attrs_attrs__: path = attr.metadata.get("path") if path: setattr(cls, attr.name, path) # 处理嵌套类的字段,拼接完整路径 for nested_name, nested_cls in cls.__dict__.items(): if hasattr(nested_cls, "__attrs_attrs__"): parent_path = getattr(cls, nested_name) for attr in nested_cls.__attrs_attrs__: full_path = f"{parent_path}.{attr.metadata.get('path')}" setattr(nested_cls, attr.name, full_path) # 触发嵌套类属性初始化 User.__init_subclass__()
使用时直接通过类访问属性获取路径:
db[UserCollection].find({User.user_id: 'newid', User.details.status: 'ALIVE'})
方法二:自定义描述符实现类/实例双访问逻辑
实现一个描述符类,类级别访问返回查询路径,实例级别访问返回字段值:
from attrs import define, field class MongoFieldDescriptor: def __init__(self, path, default=None): self.path = path self.default = default self.attr_name = path.split(".")[-1] def __get__(self, instance, owner): if instance is None: return self.path return instance.__dict__.get(self.attr_name, self.default) @define(slots=True) class User: @define() class UserDetails: status = MongoFieldDescriptor("details.status", UserStatus.ALIVE) address = MongoFieldDescriptor("details.address", None) user_id = MongoFieldDescriptor("user_id") details: UserDetails = field(factory=UserDetails)
这种方案更轻量,直接通过预定义路径实现需求,无需额外初始化逻辑。
常规替代方案
如果不想手动实现,可以直接使用基于attrs的成熟MongoDB ORM库,比如attrs-mongo或mongomantic,这些库已经封装了字段映射、查询构建、数据校验等功能,既能保证数据结构一致性,又能减少重复开发工作。
内容的提问来源于stack exchange,提问作者Gabe
相关产品推荐
相关产品推荐

