Google app engine 当我批量加载数据时,Google app engine会忽略我的自定义db属性吗? 问题是:

Google app engine 当我批量加载数据时,Google app engine会忽略我的自定义db属性吗? 问题是:,google-app-engine,validation,bulkloader,Google App Engine,Validation,Bulkloader,当我用bulkloader存储数据时,从未调用过DecimalProperty.get_value_for_datastore,因此,当我在数据存储中存储5.4时,保存方式如下:5.4;应该将其传递给get_value_for_datastore,并将其转换为如下所示的整数:54000;因为小数点后需要4位数字:5.4*10000=54000;然后返回54000/10000=5.4 我有一个模型: from google.appengine.ext import db from gae.pro

当我用bulkloader存储数据时,从未调用过DecimalProperty.get_value_for_datastore,因此,当我在数据存储中存储5.4时,保存方式如下:5.4;应该将其传递给get_value_for_datastore,并将其转换为如下所示的整数:54000;因为小数点后需要4位数字:5.4*10000=54000;然后返回54000/10000=5.4


我有一个模型:

from google.appengine.ext import db
from gae.properties.decimal_property import DecimalProperty
Articles:
    price = Decimal(4)

十进制类

from decimal import Decimal
from google.appengine.ext import db

class DecimalProperty(db.Property):
    """
    Allows Python's decimal.Decimal type to be stored in the datastore as an
    integer.  Takes care of putting the decimal point in the right place.
    """
    data_type = Decimal

    def __init__(self, dec_places, verbose_name=None, name=None, default=None,
                 required=False, validator=None, choices=None, indexed=True):
        super(DecimalProperty, self).__init__(verbose_name, name, default,
            required, validator, choices, indexed)
        self.__quantize_exp = Decimal('10') ** -dec_places
        self.__store_mul = Decimal('10') ** dec_places

    def get_value_for_datastore(self, model_inst):
        dec = super(DecimalProperty, self).get_value_for_datastore(model_inst)
        if dec is None:
            return None

        dec = dec.quantize(self.__quantize_exp)
        return int(dec * self.__store_mul)

    def make_value_from_datastore(self, value):
        if value is None:
            return None

        return Decimal(value) / self.__store_mul

    def validate(self, value):
        if value is not None and not isinstance(value, Decimal):
            raise db.BadValueError("Property %s must be a Decimal or string." % self.name)
        return super(DecimalProperty, self).validate(value)

    def empty(self, value):
        return (value is None)

我的散装装载机是:

from google.appengine.ext import bulkload
from google.appengine.api import datastore_types
import datetime

class ArticleLoader(bulkload.Loader):
    def __init__(self):
        bulkload.Loader.__init__(self, 'Article', [
            ('price', str)
        ])

if __name__ == '__main__':
    bulkload.main(ArticleLoader())
我的csv文件如下所示:

 5.4

注:

如果我输入bulkloader十进制:

from google.appengine.ext import bulkload
from google.appengine.api import datastore_types
import datetime
from decimal import Decimal

class ArticleLoader(bulkload.Loader):
    def __init__(self):
        bulkload.Loader.__init__(self, 'Article', [
            ('price', Decimal)
        ])

if __name__ == '__main__':
    bulkload.main(ArticleLoader())
我得到这个错误:

Loading from line 1...error:
Traceback (most recent call last):
  File "C:\google_appengine\google\appengine\ext\bulkload\bulkload_deprecated.py", line 306, in LoadEntities
    new_entities = loader.CreateEntity(columns, key_name=key_name)
  File "C:\google_appengine\google\appengine\ext\bulkload\bulkload_deprecated.py", line 160, in CreateEntity
    entity[name] = converter(val)
  File "C:\google_appengine\google\appengine\api\datastore.py", line 881, in __setitem__
    datastore_types.ValidateProperty(name, value)
  File "C:\google_appengine\google\appengine\api\datastore_types.py", line 1477, in ValidateProperty
    'Unsupported type for property %s: %s' % (name, v.__class__))
BadValueError: Unsupported type for property price: <class 'decimal.Decimal'>

使用bulkloader批量加载数据时,不会加载或使用模型定义—数据使用低级API直接加载到数据存储中。因此,也不会调用任何模型代码。您的“非常肮脏的解决方案”是解决这一问题的正确方法。

谢谢;)但我认为他们应该能够以某种方式保持干爽,通过重用模型中定义的代码来实现一致性,而不是通过所有验证。。但是谢谢;)
('price', to_decimal(4))

def to_decimal(dec_places):
    def converter(s):
        val = int(round(Decimal(s), dec_places) * 10 ** dec_places)
        return val

    return converter