【问题标题】:SQLAlchemy TypeDecorators and Comparison ErrorsSQLAlchemy 类型装饰器和比较错误
【发布时间】:2017-11-04 18:03:41
【问题描述】:

使用 SQLAlchemy,我定义了自己的 TypeDecorator,用于将 pandas DataFrames 存储在编码为 JSON 字符串的数据库中。

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.

所以我怀疑我的问题与强制比较器有关。我尝试了三件事,都失败了,我真的不知道下一步该怎么做:

#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

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    在我的第四次尝试中,我想我找到了答案,我直接创建了自己的比较函数,并将其插入到上面的 Type 类中。这样可以避免在我的 DataFrame 上执行运算符“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
    

    【讨论】:

      猜你喜欢
      • 2013-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-30
      • 2020-07-13
      • 2011-05-28
      相关资源
      最近更新 更多