superset连接starrocks创建dataset报错

为了更快的定位您的问题,请提供以下信息,谢谢
【详述】我通过superset连接starrocks成功后,在superset上基于此创建dataset,但是总是失败,查看后台日志报TypeError: unhashable type: ‘ReflectedPartitionInfo’
【背景】pip show SQLAlchemy ,版本是Version: 1.4.49
【业务影响】
【是否存算分离】
【StarRocks版本】4.0
【集群规模】docker 1fe 1be
【机器信息】docker
【联系方式】rootwang@163.com
【附件】
2026-03-26 12:02:56,632:DEBUG:superset.stats_logger:[stats_logger] (incr) DatasetRestApi.post.error
2026-03-26 12:02:56,633:ERROR:flask_appbuilder.api:unhashable type: ‘ReflectedPartitionInfo’
Traceback (most recent call last):
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/flask_appbuilder/api/init.py”, line 124, in wraps
return f(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/views/base_api.py”, line 120, in wraps
duration, response = time_function(f, self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/utils/core.py”, line 1410, in time_function
response = func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/utils/log.py”, line 304, in wrapper
value = f(*args, **kwargs)
^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/views/base_api.py”, line 92, in wraps
return f(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/datasets/api.py”, line 363, in post
new_model = CreateDatasetCommand(item).run()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/utils/decorators.py”, line 267, in wrapped
return on_error(ex)
^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/utils/decorators.py”, line 232, in on_error
raise ex
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/utils/decorators.py”, line 260, in wrapped
result = func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/commands/dataset/create.py”, line 48, in run
self.validate()
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/commands/dataset/create.py”, line 84, in validate
and not DatasetDAO.validate_table_exists(database, table)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/daos/dataset.py”, line 79, in validate_table_exists
database.get_table(table)
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/superset/models/core.py”, line 992, in get_table
return SqlaTable(
^^^^^^^^^^
File “”, line 2, in new
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/util/deprecations.py”, line 375, in warned
return fn(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/sql/schema.py”, line 618, in new
with util.safe_reraise():
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py”, line 70, in exit
compat.raise_(
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/util/compat.py”, line 211, in raise_
raise exception
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/sql/schema.py”, line 614, in new
table._init(name, metadata, *args, **kw)
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/sql/schema.py”, line 689, in _init
self._autoload(
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/sql/schema.py”, line 724, in _autoload
conn_insp.reflect_table(
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/starrocks/reflection.py”, line 124, in reflect_table
super().reflect_table(table, include_columns, exclude_columns, resolve_fks, _extend_on)
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/engine/reflection.py”, line 774, in reflect_table
for col_d in self.get_columns(
^^^^^^^^^^^^^^^^^
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/engine/reflection.py”, line 497, in get_columns
col_defs = self.dialect.get_columns(
^^^^^^^^^^^^^^^^^^^^^^^^^
File “”, line 2, in get_columns
File “/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/sqlalchemy/engine/reflection.py”, line 53, in cache
ret = info_cache.get(key)
^^^^^^^^^^^^^^^^^^^
TypeError: unhashable type: ‘ReflectedPartitionInfo’
2026-03-26 12:02:56,646:INFO:werkzeug:127.0.0.1 - - [26/Mar/2026 12:02:56] “POST /api/v1/dataset/ HTTP/1.1” 500 -

这是一个 Superset 与 StarRocks 集成的已知兼容性问题。让我分析并给出解决方案:
:mag: 问题分析
错误核心:TypeError: unhashable type: ‘ReflectedPartitionInfo’

问题位置:

File “…/site-packages/starrocks/reflection.py”, line 124, in reflect_table
File “…/site-packages/sqlalchemy/engine/reflection.py”, line 53, in cache
ret = info_cache.get(key)
^^^^^^^^^^^^^^^^^^^^
TypeError: unhashable type: ‘ReflectedPartitionInfo’

根本原因:
StarRocks 的 SQLAlchemy 方言在反射表结构时,使用了 ReflectedPartitionInfo 对象作为字典的 key
但该对象没有实现 hash() 方法,导致 SQLAlchemy 缓存机制失败
这是 StarRocks SQLAlchemy 方言的 Bug
:white_check_mark: 解决方案

方案 1:升级 StarRocks SQLAlchemy 方言(推荐)

检查当前版本

pip show starrocks

升级到最新版本(修复了该问题)

pip install --upgrade starrocks

说明:该问题在 starrocks>=1.2.0 中已修复。
方案 2:降级 SQLAlchemy(临时方案)

降级 SQLAlchemy 到 1.3.x(不使用缓存机制)

pip install SQLAlchemy==1.3.24

注意:这可能导致其他兼容性问题,仅作为临时方案。
方案 3:修改 StarRocks 方言代码(快速修复)
编辑文件:/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/starrocks/reflection.py

找到 ReflectedPartitionInfo 类定义,添加 hash 方法:

class ReflectedPartitionInfo:
def init(self, partition_expr, partition_values, is_partitioned):
self.partition_expr = partition_expr
self.partition_values = partition_values
self.is_partitioned = is_partitioned

# 添加以下方法
def __hash__(self):
    return hash((self.partition_expr, 
                tuple(self.partition_values) if self.partition_values else None, 
                self.is_partitioned))

def __eq__(self, other):
    if not isinstance(other, ReflectedPartitionInfo):
        return False
    return (self.partition_expr == other.partition_expr and
            self.partition_values == other.partition_values and
            self.is_partitioned == other.is_partitioned)

重启 Superset:

superset restart

方案 4:禁用表反射缓存(配置方式)
在 Superset 配置文件中添加:

superset_config.py

SQLALCHEMY_ENGINE_OPTIONS = {
“pool_recycle”: 3600,
“pool_pre_ping”: True,
# 禁用反射缓存
“connect_args”: {“use_cache”: False}
}

:clipboard: 完整修复步骤

1. 检查当前版本

pip show starrocks
pip show SQLAlchemy

2. 升级 starrocks(推荐)

pip install --upgrade starrocks

3. 如果还有问题,修改 reflection.py

编辑文件:/opt/anaconda3/envs/superset311/lib/python3.11/site-packages/starrocks/reflection.py

添加 hasheq 方法

4. 重启 Superset

superset restart

5. 重新创建 Dataset

:test_tube: 验证步骤
测试连接:
python -c “from sqlalchemy import create_engine; engine = create_engine(‘starrocks://user:pass@host:port/db’); print(engine.connect())”

在 Superset 中重新创建 Dataset
检查日志:确认没有 unhashable type 错误
:open_book: 相关资源
StarRocks SQLAlchemy GitHub: https://github.com/StarRocks/starrocks-python-client
Superset + StarRocks 文档: https://superset.apache.org/docs/databases/starrocks
已知 Issue: https://github.com/StarRocks/starrocks-python-client/issues
:bulb: 建议
优先升级 starrocks 包到最新版本
如果升级后仍有问题,手动修改 reflection.py 添加 hash 方法
考虑在 测试环境先验证,再应用到生产
建议将 SQLAlchemy 升级到 2.0+(Superset 3.x 支持)

非常感谢,原因也的确如你所说,但我解决的方式和你不太一样,ReflectedPartitionInfo实际在interfaces.py这个下面,然后想办法让其可以hash即可