2

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

正如我们所见,每个都IdentityImageIdentityRecord.

如果我有 object IdentityRecord,那么如何IdentityImage在 python 代码中找到引用该对象的所有记录?

当然,我可以执行以下操作:

IdentityImage.objects.raw({'source_identity': identity.pk})

然而,用户'source_identity'字符串文字的必要性有点违背了 ORM 的目的。在这个框架中有没有办法IdentityImage通过某种方式使用 IdentityRecord对象实例来查询集合?

4

1 回答 1

3

a 中的选择性查询pymodm.manager.Manager(例如IdentityImage.objects问题中的示例)似乎需要 adict作为getandraw方法的参数。相反,sqlalchemy 查询filter_by中的方法接受关键字参数。

如果您更喜欢关键字参数而不是字符串文字,则以下表达式似乎有效。

IdentityImage.objects.raw(dict(source_identity=identity.pk))

在该表达式中省略dict包装器表明该raw方法不接受字段名称作为关键字参数。如果修改 pymodm 以允许这样做,则此类查询的表示法会更简单。

以下代码是问题中原始代码的突变。第一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)()

根据变异代码中的定义IdentityImage,以下查询似乎在 python 3.5.3 中正常工作,与问题的示例查询中隐含的identity(的实例)具有相同的含义。IdentityRecord

IdentityImage.objects.raw(source_identity=identity.pk)

3.5 之前的 python 版本很可能需要args在变异代码中实现该函数的替代实现。我还没有完全探讨这种更改对查询表示法的影响,但我相信任何raw_query作为 a传递的查询dict仍然可以工作,无论有没有使用关键字参数的表示法,或者两种表示法的组合,一个 dictraw_query和其他字段名称的单独关键字参数。

于 2018-04-02T08:17:10.160 回答