2016-12-22 4 views
4

私はdecimal.DecimalのインスタンスをSQLAlchemyクエリから取得しています。私は、オブジェクトをシリアル化する必要があるとして、私はに対処するためのJSONシリアライザを作成しましたDecimalはAppEngineのDecimalで動作しません

import decimal 
class AlchemyEncoder(json.JSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, decimal.Decimal): 
      return str(obj) 
     return json.JSONEncoder.default(self, obj) 

不幸な事はisinstance(obj, decimal.Decimal)が(にPDBを使用していても、例えばTrueを返さないということです上記default法):

import inspect 
inspect.getfile(obj.__class__) # => '/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/decimal.pyc' 
inspect.getfile(blah.__class__) # => '/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/decimal.pyc' 

obj.__class__ # => <class 'decimal.Decimal'> 
blah = decimal.Decimal() 
blah.__class__ # => <class 'decimal.Decimal'> 
isinstance(obj, decimal.Decimal) # => False 
isinstance(blah, decimal.Decimal) # => True 
isinstance(obj, obj.__class__) # => True 

Iの両方のインスタンスが参照モジュールが同じモジュールであることを確認しました

私は本当にこれが動作していない理由を理解したいです!

EDIT

これは、AppEngineののdev_appserver.py環境で実行している場合、問題が発生しただけということが判明しました。シンプル:

isinstance(db.session.execute('SELECT amount FROM model LIMIT 1').fetchone()[0], decimal.Decimal) 

戻りFalseコンソールから実行したときのAppEngine dev_appserverとTrueを経由して要求を行います。

+2

'OBJ .__ class__ IS何とか.__ class__'の結果は何ですか? – BrenBarn

+0

@BrenBarnそれが 'False' – Aert

+0

あなたのコードにインデントエラーがあるようです...' return json.JSONEncoder.default(...) 'はおそらく' default'関数内にあるはずです。 – mgilson

答えて

1

今日これに慣れて、これについて説明した古いmailing list postを見つけました。

この質問は、先にon stackoverflowにも記載されています。アクセス/縮小stackoverflowのサーバーの負荷を容易にするために、ここで答えをペーストする:


decimal.Decimalクラスが(またはモジュールがリロードされる)Google App EngineのSDKのどこかにパッチが適用され、これが行われることが表示されます小数点をインポートするMySQL変換ライブラリとそれをインポートする間の

幸いにも、我々はMySQLの変換テーブルを更新することでこの問題を回避することができます

from MySQLdb.constants import FIELD_TYPE 
from MySQLdb.converters import conversions 
import decimal 

conversions[FIELD_TYPE.DECIMAL] = conversions[FIELD_TYPE.NEWDECIMAL] = decimal.Decimal 

それだそれ。上記のコードはMySQLクラスをリセットし、JSONエンコーダの型チェックは成功します。

の代替を使用すると、クラスのMySQLdbを探すためにためになる使用されています

class DecimalEncoder(json.JSONEncoder): 
    def default(self, o): 
     if isinstance(o, MySQLdb.converters.conversions[MySQLdb.constants.FIELD_TYPE.DECIMAL]): 
      return float(o) 
     return super(DecimalEncoder, self).default(o) 

関連する問題