通过ndb.Model构造函数填充StructuredProperty的最佳实践是什么?

时间:2018-03-30 10:05:27

标签: google-app-engine app-engine-ndb google-app-engine-python

我查看了ndb GitHub示例代码,但我找不到任何示例 其中显示了如何使用包含ndb的构造函数创建StructuredProperty实体。

这是GitHub example

如果我想使用电话号码列表初始化Contact实体,并且此电话号码列表不是PhoneNumber个对象列表,该怎么办?相反,它是一个Python词典列表。

因此,给定以下Model类:

class PhoneNumber(ndb.Model):
    """A model representing a phone number."""
    phone_type = ndb.StringProperty(
        choices=('home', 'work', 'fax', 'mobile', 'other'))
    number = ndb.StringProperty()


class Contact(ndb.Model):
    """A Contact model that uses StructuredProperty for phone numbers."""
    # Basic info.
    name = ndb.StringProperty()
    birth_day = ndb.DateProperty()

    # Address info.
    address = ndb.StringProperty()

    phone_numbers = ndb.StructuredProperty(PhoneNumber, repeated=True)

我想使用以下Python词典创建Contact

phone_number_dicts = [{"phone_type" : "home", number = 122}, {"phone_type" : "work", number = 123}]

contact = Contact(name = "some name", birthday = "some day", phone_numbers = phone_number_dicts)
  1. 我是否需要明确地将dict转换为ndb实体?
  2. 我可以覆盖将{d}转换为ndb实体并分配的ndb构造函数吗?
  3. 还有其他更好的方法吗?

2 个答案:

答案 0 :(得分:2)

而不是

phone_number_dicts = [{"phone_type" : "home", number = 122}, {"phone_type" : "work", number = 123}]
contact = Contact(name = "some name", birthday = "some day", phone_numbers = phone_number_dicts)

你需要这样的东西:

phone_numbers = [
    PhoneNumber(phone_type="home", number=123),
    PhoneNumber(phone_type="work", number=123)
]
contact = Contact(name="some name", birthday="some day", phone_numbers=phone_numbers)

即。制作PhoneNumber个实体的列表,而不是dict的列表。

您也可以将dict传递给ndb实体,以便用populate method填充它,即如果您已经拥有该行

phone_number_dicts = [{"phone_type" : "home", number = 122}, {"phone_type" : "work", number = 123}]

你无法控制,你可以做

phone_numbers = [PhoneNumber().populate(**entity) for entity in phone_number_dicts]

PhoneNumber的现有列表创建dict列表,然后再将其传递给Contact构造函数。

答案 1 :(得分:0)

只需覆盖PhoneNumber构造函数,这样就可以通过kwargs构造函数将dict作为Contact传递给它的构造函数。

class PhoneNumber(ndb.Model):
    phone_type = ndb.StringProperty(
        choices=('home', 'work', 'fax', 'mobile', 'other'))
    number = ndb.StringProperty()

    def __init__(self, *args, **kwargs):
        super(PhoneNumber, self).__init__(*args, **kwargs)
        self.__dict__.update(kwargs)


class Contact(ndb.Model):
    name = ndb.StringProperty()
    birth_day = ndb.DateProperty()
    address = ndb.StringProperty()
    phone_numbers = ndb.StructuredProperty(PhoneNumber, repeated=True)
    company_title = ndb.StringProperty()
    company_name = ndb.StringProperty()
    company_description = ndb.TextProperty()
    company_address = ndb.StringProperty()

    def __init__(self, *args, **kwargs):
        super(Contact, self).__init__(*args, **kwargs)
        if kwargs:
            self.phone_numbers = []
            for kwarg in kwargs.pop('phone_numbers'):
                if isinstance(kwarg, PhoneNumber):
                    self.phone_numbers.append(kwarg)
                else:
                    p = PhoneNumber(**kwarg)
                    self.phone_numbers.append(p)

通过这种方式,您可以将PhoneNumber实体的字典表示传递给Contact构造函数,或将PhoneNumber属性的字典表示传递给PhoneNumber构造函数。< / p>

以下是我通过dev_appserver.py交互式控制台尝试的一些测试用例:

from google.appengine.ext import ndb

from models import Contact, PhoneNumber

kwargs = {
    'phone_numbers': [{
        'phone_type': 'home',
        'number': '123',
    }, {
        'phone_type': 'work',
        'number': '456',
    }, {
        'phone_type': 'fax',
        'number': '789',
    }]
}

c = Contact(**kwargs)
print 'Test Case 1:'
print c
print

kwargs = {
    'phone_numbers': [
        PhoneNumber(**{'phone_type': 'home','number': '123'}),
        PhoneNumber(**{'phone_type': 'work','number': '456'}),
        PhoneNumber(**{'phone_type': 'fax', 'number': '789'})
    ]
}

c = Contact(**kwargs)
print 'Test Case 2:'
print c
print

c = Contact(
    phone_numbers=[
        PhoneNumber(phone_type='home', number='123'),
        PhoneNumber(phone_type='work', number='456'),
        PhoneNumber(phone_type='fax', number='789')
    ]
)
print 'Test Case 3:'
print c
print

<强>输出

Test Case 1:
Contact(phone_numbers=[PhoneNumber(number='123', phone_type='home'), 
PhoneNumber(number='456', phone_type='work'), 
PhoneNumber(number='789', phone_type='fax')])

Test Case 2:
Contact(phone_numbers=[PhoneNumber(number='123', phone_type='home'), 
PhoneNumber(number='456', phone_type='work'), 
PhoneNumber(number='789', phone_type='fax')])

Test Case 3:
Contact(phone_numbers=[PhoneNumber(number='123', phone_type='home'), 
PhoneNumber(number='456', phone_type='work'), 
PhoneNumber(number='789', phone_type='fax')])

正如所料,每个案例都会引出相同的Contact个对象。