# データをバルクロードすると、Google App Engineがカスタムdbプロパティを無視しますか？

## 問題：

データをバルクローダーで保存すると、メソッドDecimalProperty.get_value_for_datastoreが呼び出されることはありません。データストアに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)
``````

10進数のクラス

``````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

def __init__(self):
('price', str)
])

if __name__ == '__main__':
``````

`````` 5.4
``````

ノート：

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

def __init__(self):
('price', Decimal)
])

if __name__ == '__main__':
``````

``````Loading from line 1...error:
Traceback (most recent call last):
new_entities = loader.CreateEntity(columns, key_name=key_name)
entity[name] = converter(val)
datastore_types.ValidateProperty(name, value)
'Unsupported type for property %s: %s' % (name, v.__class__))
BadValueError: Unsupported type for property price:
``````

## 非常に厄介な解決策：

``````('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
``````
1

## 1 答え

バルクローダーでデータをバルクロードすると、モデル定義がロードまたは使用されません。データは、低レベルAPIを使用してデータストアに直接ロードされます。その結果、どちらのモデルコードも呼び出されません。あなたの「非常に汚れた解決策」はこれについて正しい道です。

2

ありがとう;）しかし、私は彼らが何とかDRYになるべきだと思います。モデルに定義されたコードを一貫性のために再利用し、すべてのバリデーションをバイパスしません。