3

我最近经常使用 MongoEngine。除了 MongoDB 集成之外,我喜欢明确定义实体结构的想法。字段定义使代码更容易理解。此外,使用这些定义,我可以验证对象以捕获潜在的错误或更准确地序列化/反序列化它们。

MongoEngine 的问题在于它是专门为与存储引擎一起工作而设计的。这同样适用于 Django 和 SQLAlchemy 模型,它们也缺少列表和集合类型。那么,我的问题是,是否有 Python 的对象模式/模型库可以进行自动对象验证和序列化,但没有对象关系映射或任何其他花哨的东西

让我举个例子吧。

class Wheel(Entity):
    radius = FloatField(1.0)


class Bicycle(Entity):
    front = EntityField(Wheel)
    back = EntityField(Wheel)


class Owner(Entity):
    name = StringField()
    bicycles = ListField(EntityField(Bicycle))


owner = Owner(name='Eser Aygün', bicycles=[])

bmx = Bicycle()
bmx.front = Wheel()
bmx.back = Wheel()

trek = Bicycle()
trek.front = Wheel(1.2)
trek.back = Wheel(1.2)

owner.bicycles.append(bmx)
owner.bicycles.append(trek)

owner.validate()  # checks the structure recursively

给定结构,序列化和反序列化对象也很容易。例如,owner.jsonify()可能返回字典

{
    'name': 'Eser Aygün',
    'bicycles': [{
        'front': {
            radius: 1.0
        },
        'back': {
            radius: 1.0
        }
    }, {
        'front': {
            radius: 1.2
        },
        'back': {
            radius: 1.2
        }
    }],
}

并且您可以轻松地将其转换回调用owner.dejsonify(dic)

4

4 回答 4

4

如果有人还在寻找,因为python-entities有一段时间没有更新,那里有一些很好的库:

于 2016-01-27T15:28:32.940 回答
1

您所描述的可以使用remoteobjects来实现,它包含一种机制(称为dataobject),允许您定义对象的结构,以便可以对其进行验证,并且可以轻松地将其编组到 JSON 和从 JSON 编组。

它还包括一些用于构建发出 HTTP 请求的 REST 客户端库的功能,但不需要使用这部分。

remoteobjects发行版没有特定StringFieldIntegerField类型,但很容易实现它们。这是我维护的代码库中的一个示例,该示例BooleanField使用remoteobjects

class BooleanField(dataobject.fields.Field):

    def encode(self, value):
        if value is not None and type(value) is not bool:
            raise TypeError("Requires boolean")
        return super(BooleanField, self).encode(value)

然后可以在对象定义中使用它:

class ThingWithBoolean(dataobject.DataObject):
    my_boolean = BooleanField()

进而:

thing = ThingWithBoolean.from_dict({"my_boolean":true})
thing.my_boolean = "hello"
return json.dumps(thing.to_dict()) # will fail because my_boolean is not a boolean
于 2013-03-28T22:19:25.953 回答
1

查看mongopersist,它使用 mongo 作为 Python 对象(如 ZODB)的持久层。它不执行模式验证,但它允许您在 Mongo 和 Python 之间透明地移动对象。

对于验证或其他序列化/反序列化场景(例如表单),请考虑colander. 漏勺项目说明:

Colander 可用作验证和反序列化通过 XML、JSON、HTML 表单发布或任何其他同样简单的数据序列化获得的数据的系统。它在 Python 2.6、2.7 和 3.2 上运行。滤锅可用于:

  • 定义数据模式。
  • 在针对数据模式验证数据结构后,将由字符串、映射和列表组成的数据结构反序列化为任意 Python 结构。
  • 将任意 Python 结构序列化为由字符串、映射和列表组成的数据结构。
于 2013-03-28T22:22:51.483 回答
0

正如我之前在评论中所说,我决定发明自己的轮子。我开始实现一个开源 Python 库Entities,它正是我想要的。您可以从https://github.com/eseraygun/python-entities/查看。

该库支持递归和非递归集合类型(列表、集合和字典)、嵌套实体和引用字段。它可以为任何复杂的实体自动验证、序列化、反序列化和生成可散列密钥。(事实上​​,反序列化功能还没有完成。)

这是你如何使用它:

from entities import *

class Account(Entity):
    id = IntegerField(group=PRIMARY)  # this field is in primary key group
    iban = IntegerField(group=SECONDARY)  # this is in secondary key group
    balance = FloatField(default=0.0)

class Name(Entity):
    first_name = StringField(group=SECONDARY)
    last_name = StringField(group=SECONDARY)

class Customer(Entity):
    id = IntegerField(group=PRIMARY)
    name = EntityField(Name, group=SECONDARY)
    accounts = ListField(ReferenceField(Account), default=list)

# Create Account objects.
a_1 = Account(1, 111, 10.0)  # __init__() recognizes positional arguments
a_2 = Account(id=2, iban=222, balance=20.0)  # as well as keyword arguments

# Generate hashable key using primary key.
print a_1.keyify()  # prints '(1,)'

# Generate hashable key using secondary key.
print a_2.keyify(SECONDARY)  # prints '(222,)'

# Create Customer object.
c = Customer(1, Name('eser', 'aygun'))

# Generate hashable key using primary key.
print c.keyify()  # prints '(1,)'

# Generate hashable key using secondary key.
print c.keyify(SECONDARY)  # prints '(('eser', 'aygun'),)'

# Try validating an invalid object.
c.accounts.append(123)
try:
    c.validate()  # fails
except ValidationError:
    print 'accounts list is only for Account objects'

# Try validating a valid object.
c.accounts = [a_1, a_2]
c.validate()  # succeeds
于 2013-04-01T20:34:46.187 回答