2017-10-14 7 views
1

SQLAlchemy를 사용하여 JSON 문자열로 인코딩 된 데이터베이스에 팬더 DataFrames를 저장하기위한 자체 TypeDecorator를 정의했습니다.SQLAlchemy TypeDecorators 및 비교 오류

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을 변경하고 데이터베이스를 변경하려고하면 문제가 발생합니다.

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

그래서 나는 내 문제가 강요 비교기 함께 할 수있는 뭔가가 생각 : 나는

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

를 호출 할 때 나는 문제되는 값을 비교를 가리키는 역 추적을 얻을. 나는 세 가지를 시도 모두 실패하고 난 정말 다음에 무엇을 모른다 : 나는, 내가 직접 내가 삽입 내 자신의 비교 함수를 만들 답을 찾은 것 같아 내 네 번째 시도에서

#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 클래스.

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 

이러한 성격의 또 다른 문제는 나중에 내 코드에 출연 : 이것은 'X == y는'내 DataFrames에서 수행되는 조작을 방지 할 수 있습니다. 해결책은 먼저 자연 비교를 시도하기 위해 위를 수정 한 다음 실패한 경우 위를 구현하는 것입니다.

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