我在项目中使用pymodm
作为ORM。
我有以下简单的案例:
class IdentityRecord(MongoModel):
alias = fields.CharField() # normal name for identity
class IdentityImage(MongoModel):
filename = fields.CharField() # filename on filesystem
source_identity = fields.ReferenceField(IdentityRecord) # reference to an identity
我们可以看到,每个IdentityImage
都指IdentityRecord
。
如果我有对象IdentityRecord
,那么如何在python代码中找到IdentityImage
中引用该对象的所有记录?
当然,我可以做到以下几点:
IdentityImage.objects.raw({'source_identity': identity.pk})
然而,用户'source_identity'
字符串文字的必要性有点违背了ORM的目的。在此框架中是否有任何方法可以使用IdentityImage
对象的实例以某种方式查询IdentityRecord
集合?
答案 0 :(得分:3)
pymodm.manager.Manager
中的选择性查询(例如问题示例中的IdentityImage.objects
)似乎需要dict
作为get
和{{1}的参数}} 方法。相反,sqlalchemy query中的raw
方法接受关键字参数。
如果您更喜欢字符串文字的关键字参数,则以下表达式似乎有效。
filter_by
省略该表达式中的IdentityImage.objects.raw(dict(source_identity=identity.pk))
包装器会发现dict
方法不接受字段名称作为关键字参数。如果pymodm被修改为允许,那么这种查询的表示法会更简单。
以下代码是问题中原始代码的变体。第一个raw
行隐含在原始代码中,并在此处显式显示。其他两个import
行可以定义和使用新类import
。除了新类KWQuerySet
的辅助函数之外,唯一的另一个变化是最后一行,它是原始代码中一个类中的一个新属性,它使用了新类。
args
通过变异代码中from pymodm import MongoModel, fields
from pymodm.queryset import QuerySet
from pymodm.manager import Manager
def args(arg=None, **kwargs):
return {**arg, **kwargs} if arg else kwargs
class KWQuerySet(QuerySet):
def raw(self, raw_query=None, **kwargs):
return super().raw(args(raw_query, **kwargs))
def get(self, raw_query=None, **kwargs):
return super().get(args(raw_query, **kwargs))
class IdentityRecord(MongoModel):
alias = fields.CharField() # normal name for identity
class IdentityImage(MongoModel):
filename = fields.CharField() # filename on filesystem
source_identity = fields.ReferenceField(IdentityRecord) # reference to an identity
objects = Manager.from_queryset(KWQuerySet)()
的定义,以下查询似乎在python 3.5.3中正常工作,与IdentityImage
(identity
的实例)具有相同的含义隐含在问题的示例查询中。
IdentityRecord
3.5之前的python版本可能需要在变异代码中替代实现IdentityImage.objects.raw(source_identity=identity.pk)
函数。我还没有充分探讨这种更改对查询表示法的影响,但我相信任何将args
作为raw_query
传递的查询仍然有效,无论是否使用关键字参数的符号,或者两种表示法的组合,dict
的词典和其他字段名称的单独关键字参数。