升级2.1.4版本与SQLAlchemy不兼容,导致Supetset获取表字段时报错

Viewed 143

Supetset报错:

2024-07-15 10:25:35,762:ERROR:flask_appbuilder.api:NullType() takes no arguments
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/flask_appbuilder/api/init.py", line 110, in wraps
return f(self, *args, **kwargs)
File "/app/superset/views/base_api.py", line 127, in wraps
raise ex
File "/app/superset/views/base_api.py", line 121, in wraps
duration, response = time_function(f, self, *args, **kwargs)
File "/app/superset/utils/core.py", line 1526, in time_function
response = func(*args, **kwargs)
File "/app/superset/utils/log.py", line 255, in wrapper
value = f(*args, **kwargs)
File "/app/superset/databases/api.py", line 728, in table_metadata
table_info = get_table_metadata(database, table_name, schema_name)
File "/app/superset/databases/utils.py", line 67, in get_table_metadata
columns = database.get_columns(table_name, schema_name)
File "/app/superset/models/core.py", line 847, in get_columns
return self.db_engine_spec.get_columns(inspector, table_name, schema)
File "/app/superset/db_engine_specs/base.py", line 1294, in get_columns
cast(list[SQLAColumnType], inspector.get_columns(table_name, schema))
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py", line 497, in get_columns
col_defs = self.dialect.get_columns(
File "", line 2, in get_columns
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py", line 55, in cache
ret = fn(self, con, *args, **kw)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/dialects/mysql/base.py", line 2832, in get_columns
parsed_state = self._parsed_state_or_create(
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/dialects/mysql/base.py", line 3074, in _parsed_state_or_create
return self._setup_parser(
File "", line 2, in _setup_parser
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py", line 55, in cache
ret = fn(self, con, *args, **kw)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/dialects/mysql/base.py", line 3110, in _setup_parser
return parser.parse(sql, charset)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/dialects/mysql/reflection.py", line 46, in parse
self._parse_column(line, state)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/dialects/mysql/reflection.py", line 224, in _parse_column
type_instance = col_type(*type_args, **type_kw)
TypeError: NullType() takes no arguments

定位原因是:2.1.4版本与SQLAlchemy不兼容
测试脚本:

import sys
from sqlalchemy import create_engine, inspect
from sqlalchemy.exc import SQLAlchemyError


def get_database_info(db_url, table_name=None):
    try:
        # 创建数据库引擎
        engine = create_engine(db_url)

        # 创建检查器
        inspector = inspect(engine)

        # 获取所有表名
        tables = inspector.get_table_names()
        print("Tables in the database:")
        for t in tables:
            print(f"- {t}")

        if table_name:
            if table_name not in tables:
                print(f"\nError: Table '{table_name}' not found in the database.")
                return

            print(f"\nDetailed information for table '{table_name}':")
            
            # 获取表的列信息
            columns = inspector.get_columns(table_name)
            print("\nColumns:")
            for column in columns:
                print(f"- {column['name']}: {column['type']}")

            # 获取表的创建语句
            with engine.connect() as connection:
                result = connection.execute(f"SHOW CREATE TABLE {table_name}")
                create_statement = result.fetchone()[1]
                print(f"\nCreate statement:")
                print(create_statement)

    except SQLAlchemyError as e:
        print("An error occurred:", str(e))

    finally:
        if 'engine' in locals():
            engine.dispose()

if __name__ == "__main__":
    # 数据库连接信息
    username = ""
    password = ""
    host = ""
    port = "9030"  # MySQL 默认端口
    database = ""

    # 构建数据库 URL
    db_url = f"mysql+pymysql://{username}:{password}@{host}:{port}/{database}"

    # 如果提供了表名作为命令行参数,则使用它
    table_name = sys.argv[1] if len(sys.argv) > 1 else None

    get_database_info(db_url, table_name)

脚本报错:

/Users/sbs/vscode/Python/supetset.py:28: SAWarning: Did not recognize type 'DATE' of column 'data_dt'
columns = inspector.get_columns(table_name)
/Users/sbs/vscode/Python/supetset.py:28: SAWarning: Did not recognize type 'VARCHAR' of column 'rule_name'
columns = inspector.get_columns(table_name)
Traceback (most recent call last):
File "/Users/sbs/vscode/Python/supetset.py", line 61, in
get_database_info(db_url, table_name)
File "/Users/sbs/vscode/Python/supetset.py", line 28, in get_database_info
columns = inspector.get_columns(table_name)
File "/Users/sbs/Library/Python/3.9/lib/python/site-packages/sqlalchemy/engine/reflection.py", line 859, in get_columns
col_defs = self.dialect.get_columns(
File "", line 2, in get_columns
File "/Users/sbs/Library/Python/3.9/lib/python/site-packages/sqlalchemy/engine/reflection.py", line 97, in cache
ret = fn(self, con, *args, **kw)
File "/Users/sbs/Library/Python/3.9/lib/python/site-packages/sqlalchemy/dialects/mysql/base.py", line 2964, in get_columns
parsed_state = self._parsed_state_or_create(
File "/Users/sbs/Library/Python/3.9/lib/python/site-packages/sqlalchemy/dialects/mysql/base.py", line 3224, in _parsed_state_or_create
return self._setup_parser(
File "", line 2, in _setup_parser
File "/Users/sbs/Library/Python/3.9/lib/python/site-packages/sqlalchemy/engine/reflection.py", line 97, in cache
ret = fn(self, con, *args, **kw)
File "/Users/sbs/Library/Python/3.9/lib/python/site-packages/sqlalchemy/dialects/mysql/base.py", line 3260, in _setup_parser
return parser.parse(sql, charset)
File "/Users/sbs/Library/Python/3.9/lib/python/site-packages/sqlalchemy/dialects/mysql/reflection.py", line 48, in parse
self._parse_column(line, state)
File "/Users/sbs/Library/Python/3.9/lib/python/site-packages/sqlalchemy/dialects/mysql/reflection.py", line 284, in _parse_column
type_instance = col_type(*type_args, **type_kw)
TypeError: NullType() takes no arguments

AI分析:
警告信息: SQLAlchemy 无法识别某些列的类型,包括 DATE, BIGINT, INT, 和 VARCHAR。这表明 SQLAlchemy 可能没有正确配置 MySQL 方言或缺少某些类型映射。

错误: 最终的错误是 TypeError: NullType() takes no arguments,这与你之前在 Superset 中遇到的错误相同。

问题原因: 这个问题很可能是由于 SQLAlchemy 版本与 MySQL 版本不兼容,或者 SQLAlchemy 的 MySQL 方言配置不正确导致的。

Doris版本:2.1.4
SQLAlchemy:24.1.2

2 Answers

Did not recognize type 'DATE' of column 'data_dt'
columns = inspector.get_columns(table_name)
/Users/sbs/vscode/Python/supetset.py:28: SAWarning: Did not recognize type 'VARCHAR' of column 'rule_name'

可以提供下这个表的建表语句么?