2017-10-14 29 views
1

SQLAlchemyの使用私は、JSON文字列としてエンコードされたデータベースにpandas DataFramesを格納するための独自のTypeDecoratorを定義しました。SQLAlchemy型デシレータと比較エラー

class db_JsonEncodedDataFrameWithTimezone(db.TypeDecorator): 
    impl = db.Text 

    def process_bind_param(self, value, dialect): 
     if value is not None and isinstance(value, pd.DataFrame): 
      timezone = value.index.tz.zone 
      df_json = value.to_json(orient="index") 
      data = {'timezone': timezone, 'df': df_json, 'index_name': value.index.name} 
      value = json.dumps(data) 
     return value 

    def process_result_value(self, value, dialect): 
     if value is not None: 
      data = json.loads(value) 
      df = pd.read_json(data['df'], orient="index") 
      df.index = df.index.tz_localize('UTC') 
      df.index = df.index.tz_convert(data['timezone']) 
      df.index.name = data['index_name'] 
      value = df 
     return value 

これは初めてデータベースを保存しても正常に動作し、読み込みにも問題ありません。

値を増やす、つまりDataFrameを変更してデータベースを変更しようとすると問題が発生します。私は

db.session.add(entity) 
db.session.commit() 

を起動すると、私は問題点の値を比較するポイントトレースバックを得る:

x == y 
ValueError: Can only compare identically-labeled DataFrame Objects. 

だから私は私の問題は、強制するコンパレータとは何かを持っている疑いがあります。私はすべてが失敗していると私は本当に次に何をすべきか分からない、3つのことを試してみました:

#1st failed solution attempt inserting 
coerce_to_is_types = (pd.DataFrame,) 

#2nd failed solution attempt inserting 
def coerce_compared_value(self, op, value): 
    return self.impl.coerce_compared_value(op, value) 

#3rd failed solution attempt 
class comparator_factory(db.Text.comparator_factory): 
    def __eq__(self, other): 
     try: 
      value = (self == other).all().all() 
     except ValueError: 
      value = False 
     return value 

答えて

0

私は答えを見つけたと思う私の第四の試みで、私は直接私が挿入された自分自身の比較関数を作成します上記のTypeクラスこれは、私のDataFramesで実行されている演算子 'x == y'を避けます。

def compare_values(self, x, y): 
    from pandas.util.testing import assert_frame_equal 
    try: 
     assert_frame_equal(x, y, check_names=True, check_like=True) 
     return True 
    except (AssertionError, ValueError, TypeError): 
     return False 

この性質の別の問題は後で私のコードに現れました。解決策は、最初の自然比較を試みるために上記を修正することでした。それが失敗した場合は、上記を実装してください:

try: 
    value = x == y 
except: 
    # some other overwriting comparision method such as above