
StarRocks Schema 管理与迁移SQLAlchemy Alembic sqlacodegen 完整实战指南【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocksStarRocks 官方提供的 Python 生态工具链starrocksSQLAlchemy 方言、Alembic 迁移扩展、sqlacodegen 反向建模让数据仓库的 Schema 管理进入声明式、版本化、自动化的现代化阶段。本文以 docs/en/integrations/starrocks_sqlalchemy.md 为核心结合 contrib/starrocks-python-client 中的真实源码实现完整讲解如何用 Python 定义 StarRocks 表、视图、物化视图并通过 Alembic 自动生成与执行迁移脚本最终帮助你告别手写ALTER TABLE的易错与不可追踪建立跨环境一致的 Schema 交付流程。为什么 StarRocks 也需要 Schema 迁移很多用户习惯直接用 SQL DDL 管理 StarRocks 的表、视图和物化视图。但随着项目规模增长手工维护ALTER TABLE语句会带来两个突出问题易出错列变更、属性调整分散在不同脚本中难以确保生产环境执行了正确的组合难追踪谁在什么时间改了什么、如何回滚、开发/预发/生产三套环境的 Schema 是否一致全都无法回答。StarRocks SQLAlchemy 方言dialect 名为starrocks正是为这一场景而生它提供完整的 SQLAlchemy 模型层覆盖 StarRocks 的表tables、视图views、物化视图materialized views面向表结构与表属性含视图、物化视图的声明式定义能力与Alembic深度集成自动检测当前 StarRocks Schema 与模型之间的差异并生成迁移脚本CREATE/DROP/ALTER兼容sqlacodegen可从现有数据库反向生成模型代码。这意味着 Python 用户可以用声明式 版本控制 自动化的方式维护 StarRocks Schema。在仓库中该方言与 Alembic 扩展的实现集中在 contrib/starrocks-python-client/starrocks/alembic 目录其中__init__.py明确导出了三个关键组件见 alembic/init.pyStarRocksImplAlembic 的 DDL 实现类render_column_typeStarRocks 列类型的渲染回调include_object_for_view_mv视图 / 物化视图的对象过滤回调旧版本中的include_object_for_view_为早期命名。核心价值为什么团队选择 Alembic StarRocks 方言尽管 Schema 迁移传统上被认为是 OLTP 数据库的专利但在 StarRocks 这类数据仓库系统中同样价值巨大。团队使用 Alembic 与 StarRocks 方言可以获得以下收益声明式 Schema 定义一旦在 Python ORM 模型或 SQLAlchemy Core 风格中定义好 Schema就不再需要手写ALTER TABLE。StarRocks 方言将所有 StarRocks 专属属性以starrocks_前缀的关键字参数承载例如starrocks_primary_key、starrocks_distributed_by、starrocks_properties。这些参数名的定义可参见 common/params.py 中的TableInfoKeyWithPrefix常量类。自动 diff 与自动生成Alembic 会对比当前 StarRocks 实际 Schema与你的 SQLAlchemy 模型自动生成迁移脚本CREATE/DROP/ALTER无需手工编写 DDL。方言在 alembic/compare.py 中实现了 StarRocks 专属的 diff 逻辑包括复杂类型ARRAY/MAP/STRUCT的递归比较、meta.STRING与库端VARCHAR(65533)等特殊类型的等价判断见 alembic/starrocks.py 的compare_type实现。可审查、可版本控制的迁移每次 Schema 变更都会成为一个 Python 迁移文件团队可以像 review 代码一样 review Schema 变更需要时也能回滚。跨环境一致的工作流同一套迁移流程可以应用到开发、预发、生产环境彻底消除环境漂移。安装与连接环境前置要求组件版本要求StarRocks Python clientstarrocks包1.3.2 或更高SQLAlchemy1.4 或更高推荐 2.0使用sqlacodegen必须为 2.0Alembic1.16 或更高安装 StarRocks Python clientpip install starrocks从仓库中的 README.md 可以看到该包支持 Python 3.10、 3.14官方建议在虚拟环境中安装以避免与系统级包冲突。连接 StarRocks使用如下 URL 连接你的 StarRocks 集群starrocks://user:passwordFE_host:query_port/[catalog.]database各字段含义user连接集群的用户名password用户密码FE_hostFEFrontendIP 地址query_portFE 的query_port默认9030catalog数据库所在的 catalog 名称可省略默认default_catalogdatabase要连接的数据库名称。此外该包还提供了基于asyncmy的异步驱动连接串格式为starrocksasyncmy://user:passwordFE_host:query_port/[catalog.]database。异步方言的实现见 starrocks/asyncmy.py它继承自同步StarRocksDialect配合sqlalchemy.ext.asyncio.create_async_engine使用完整异步示例见 README.md。安装完成后可以用下面的代码快速验证连通性from sqlalchemy import create_engine, text # you need to create mydatabase first engine create_engine(starrocks://rootlocalhost:9030/mydatabase) with engine.connect() as conn: conn.execute(text(SELECT 1)).fetchall() print(Connection successful!)定义 StarRocks 模型声明式 ORMStarRocks 方言支持三种对象类型表Tables视图Views物化视图Materialized Views并支持以下 StarRocks 专属表属性ENGINEOLAPKey 模型DUPLICATE KEY/PRIMARY KEY/UNIQUE KEY/AGGREGATE KEYPARTITION BY变体RANGE / LIST / 表达式分区DISTRIBUTED BY变体HASH / RANDOMORDER BY表属性如replication_num、storage_medium:::important 使用前必读StarRocks 方言选项以starrocks_前缀的关键字参数传入。starrocks_前缀必须小写后缀部分大小写均可例如PRIMARY_KEY与primary_key等价。如果指定了表 Key如starrocks_primary_keyid涉及的列必须同时在Column(...)中标记primary_keyTrue否则 SQLAlchemy metadata 与 Alembic autogenerate 的行为会不正确。 :::以下示例均反映真实公开 API 与参数名。从源码 common/params.py 可以看到方言名常量DialectName starrocks、前缀常量SRKwargsPrefix starrocks_而starrocks_properties等具体参数键在TableInfoKeyWithPrefix中集中定义。表定义示例ORMDeclarative风格StarRocks 表选项既可以在 ORM 风格中通过__table_args__指定也可以在 Core 风格中通过Table(..., starrocks_......)指定。from sqlalchemy import create_engine from sqlalchemy.orm import Mapped, declarative_base, mapped_column from starrocks import INTEGER, STRING # with the same engine as the quick test engine create_engine(starrocks://rootlocalhost:9030/mydatabase) Base declarative_base() class MyTable(Base): __tablename__ my_orm_table id: Mapped[int] mapped_column(INTEGER, primary_keyTrue) name: Mapped[str] mapped_column(STRING) __table_args__ { comment: table comment, starrocks_primary_key: id, starrocks_distributed_by: HASH(id) BUCKETS 10, starrocks_properties: {replication_num: 1} } # Create the table in the database Base.metadata.create_all(engine)表定义示例Core 风格from sqlalchemy import Column, MetaData, Table, create_engine from starrocks import INTEGER, VARCHAR # with the same engine as the quick test engine create_engine(starrocks://rootlocalhost:9030/mydatabase) metadata MetaData() my_core_table Table( my_core_table, metadata, Column(id, INTEGER, primary_keyTrue), Column(name, VARCHAR(50)), # StarRocks-specific arguments starrocks_primary_keyid, starrocks_distributed_byHASH(id) BUCKETS 10, starrocks_properties{replication_num: 1} ) # Create the table in the database metadata.create_all(engine)关于表属性与数据类型的完整参考见 docs/usage_guide/tables.md。视图定义示例视图推荐使用columns参数以 dict 列表形式声明列每个 dict 含name/comment下面的示例基于已存在的表my_core_tablefrom starrocks.schema import View # Reuse the metadata from the Core table example above metadata my_core_table.metadata user_view View( user_view, metadata, definitionSELECT id, name FROM my_core_table WHERE name IS NOT NULL, columns[ {name: id, comment: ID}, {name: name, comment: Name}, ], commentActive users, )从源码看View继承自 SQLAlchemy 的Table见 starrocks/sql/schema.py其definition参数既支持 SQL 字符串也支持 SQLAlchemySelectable对象columns参数支持三种形式Column对象、纯字符串列名、{name: ..., comment: ...}dict。注意 StarRocks 视图列只支持 name 和 comment不支持类型与可空性_normalize_columns中统一以STRING()作为占位类型。视图还可通过starrocks_securityINVOKER指定安全模式StarRocks 不支持DEFINER。更多视图选项与限制见 docs/usage_guide/views.md。物化视图定义示例物化视图的定义方式与视图类似starrocks_refresh属性是一个语法字符串用于指定刷新策略from starrocks.schema import MaterializedView # Reuse the metadata from the Core table example above metadata my_core_table.metadata # Create a simple Materialized View (asynchronous refresh) user_stats_ MaterializedView( user_stats_, metadata, definitionSELECT id, COUNT(*) AS cnt FROM my_core_table GROUP BY id, starrocks_refreshASYNC )源码中MaterializedView继承自View见 starrocks/sql/schema.py额外支持以下starrocks_参数starrocks_partition_by分区表达式如date_trunc(day, created_at)starrocks_distributed_by分布方式如HASH(user_id) BUCKETS 10starrocks_order_by排序列如user_id, created_atstarrocks_refresh刷新模式格式为[IMMEDIATE|DEFERRED] [ASYNC|MANUAL]如ASYNC、MANUAL、IMMEDIATE ASYNCstarrocks_properties附加属性 dict如{replication_num: 3}。更多物化视图选项与 ALTER 限制见 docs/usage_guide/materialized_views.md。Alembic 集成StarRocks SQLAlchemy 方言对 Alembic 提供了完整支持创建 / 删除表Create / Drop table创建 / 删除视图Create / Drop view创建 / 删除物化视图Create / Drop materialized view检测 StarRocks 专属属性如表属性、分布方式上支持的变更这使得 Alembic 的autogenerate能够正常工作。方言的 DDL 实现类StarRocksImpl继承自 MySQL 实现见 alembic/starrocks.py并重写了version_table_impl由于 StarRocks 要求表必须有主键Alembic 版本表alembic_version被构建为id BIGINT autoincrement主键 version_num VARCHAR(32)的结构并默认指定starrocks_primary_keyid同时支持通过version_table_kwargs传入额外的starrocks_*参数例如为单 BE 开发集群设置replication_num。初始化 Alembic初始化 Alembicalembic init migrations在alembic.ini中配置数据库 URL# alembic.ini sqlalchemy.url starrocks://user:passwordFE_host:query_port/[catalog.]database可选开启 StarRocks 方言日志在alembic.ini中注册starrockslogger可以在日志中观察表级检测到的变更。具体配置方法见 docs/usage_guide/alembic.md# alembic.ini [loggers] keys root,sqlalchemy,alembic,starrocks # Add following lines after [logger_alembic] section [logger_starrocks] level INFO handlers qualname starrocks编辑env.py注意offline 与 online 两条路径都需要配置from alembic import context from starrocks.alembic import render_column_type, include_object_for_view_ from starrocks.alembic.starrocks import StarRocksImpl # noqa: F401 (ensure impl registered) from myapp.models import Base # adjust to your project target_metadata Base.metadata def run_migrations_offline() - None: url context.config.get_main_option(sqlalchemy.url) context.configure( urlurl, target_metadatatarget_metadata, render_itemrender_column_type, include_objectinclude_object_for_view_ ) with context.begin_transaction(): context.run_migrations() def run_migrations_online() - None: # ... create engine and connect as in alembic default env.py ... with connectable.connect() as connection: context.configure( connectionconnection, target_metadatatarget_metadata, render_itemrender_column_type, include_objectinclude_object_for_view_ ) with context.begin_transaction(): context.run_migrations()说明include_object_for_view_是早期命名在仓库当前代码中该函数已更名为include_object_for_view_mv见 alembic/init.py两者选其一按你的包版本适配即可。视图/物化视图比较的规范化 schemacanonicalization在 StarRocks4.0.6 之前的版本上视图或物化视图的定义会以引擎自身的规范形式存储可能与模型中的 SQL 在文本上存在差异例如去掉col AS col别名、增加括号等但语义相同。为避免每次 autogenerate 都误报幽灵变更phantom change方言会将模型定义通过临时视图做一次往返round-trip取回引擎存储的规范形式后再与库端比较。默认情况下该临时视图创建在被比较对象所在的 schema 中因此迁移用户需要对每个包含视图/MV 的 schema 都具备建视图权限。如果你的用户权限受限可以设置starrocks_temp_view_schema指向一个专用 schema并只在该 schema 上授予所需权限。使用__…__风格命名例如__alembic_canon__可以让该 schema 的用途一目了然它可以是用户可写的任意 schema包括已有的version_table_schema# env.py context.configure( # ... your existing parameters (render_item, include_object, etc.) ... starrocks_temp_view_schema__alembic_canon__, # host the transient comparison view here )在源码 alembic/compare.py 中该选项常量被定义为TEMP_VIEW_SCHEMA_OPT starrocks_temp_view_schema比较逻辑会优先使用它否则回落到被比较对象自身的 schema_configured_temp_view_schema(autogen_context) or resolved_schema。为迁移用户在该 schema 上授予创建 → 回读 → 删除往返所需权限仅有CREATE VIEW不够GRANT CREATE VIEW ON DATABASE __alembic_canon__ TO user; GRANT SELECT, DROP ON ALL VIEWS IN DATABASE __alembic_canon__ TO user;当starrocks_temp_view_schema未设置时行为不变临时视图创建在被比较对象自身的 schema 中。如果临时视图无法创建缺少权限或引用的对象尚不存在比较逻辑会记录 DEBUG 日志并回退到进程内的 AST/正则规范化。自动生成迁移脚本alembic revision --autogenerate -m initial schemaAlembic 会对比 SQLAlchemy 模型与 StarRocks 实际 Schema并输出正确的 DDL。应用迁移alembic upgrade head降级downgrade在可逆的情况下同样支持。:::important 事务性警告 StarRocks 的 DDL跨多条语句不具备事务性。如果升级中途失败你可能需要先检查已应用的部分并手工修复例如编写补偿迁移或手动执行 DDL然后才能重新执行。 :::支持的 Schema 变更操作方言支持 Alembic autogenerate 处理以下变更表创建 / 删除以及通过starrocks_*声明的 StarRocks 专属属性的 diff在 StarRocks ALTER 支持范围内视图创建 / 删除 / 修改主要是定义相关的变更部分属性不可变物化视图创建 / 删除 / 修改仅限于可变更子句如刷新策略与属性。有些 StarRocks DDL 变更不可逆或不可 ALTER只能通过删除并重建表/视图/物化视图来完成。如果在方言中指定了这些变更autogenerate 会警告或直接报错而不是静默生成不可用的 SQL。从源码可以精确地看出哪些属性支持 ALTER。表级属性启用矩阵定义在 common/params.py 的AlterTableEnablement中属性是否支持 ALTER说明ENGINE❌ 否建表后不可修改引擎KEYKey 模型✅ 是列可调整但列类型不支持修改COMMENT✅ 是PARTITION_BY❌ 否分区表达式不可修改DISTRIBUTED_BY✅ 是ORDER_BY✅ 是PROPERTIES✅ 是而物化视图的启用矩阵定义在AlterMVEnablement见 common/params.py中仅RENAME、REFRESH、PROPERTIES支持 ALTERKEY、COMMENT、PARTITION_BY、DISTRIBUTED_BY、ORDER_BY均不可变。端到端示例初学者推荐阅读本节展示一个可运行的完整工作流并标注了每个暂停点——建议停下来审查生成的产物。步骤 1创建项目目录并初始化 Alembicmkdir my_sr_alembic_project cd my_sr_alembic_project alembic init alembic步骤 2配置alembic.ini编辑alembic.ini中的 URLsqlalchemy.url starrocks://rootlocalhost:9030/mydatabase步骤 3定义模型为模型创建包mkdir -p myapp touch myapp/__init__.py在包中创建myapp/models.py放入表 / 视图 / 物化视图定义:::note 使用 Alembic 迁移时不要在 models 模块中调用metadata.create_all(engine)。 :::from sqlalchemy import Column, Table from sqlalchemy.orm import Mapped, declarative_base, mapped_column from starrocks import INTEGER, STRING, VARCHAR from starrocks.schema import MaterializedView, View Base declarative_base() # --- ORM table --- class MyOrmTable(Base): __tablename__ my_orm_table id: Mapped[int] mapped_column(INTEGER, primary_keyTrue) name: Mapped[str] mapped_column(STRING) __table_args__ { comment: table comment, starrocks_primary_key: id, starrocks_distributed_by: HASH(id) BUCKETS 10, starrocks_properties: {replication_num: 1}, } # --- Core table on the same metadata (important for Alembic target_metadata) --- my_core_table Table( my_core_table, Base.metadata, Column(id, INTEGER, primary_keyTrue), Column(name, VARCHAR(50)), commentcore table comment, starrocks_primary_keyid, starrocks_distributed_byHASH(id) BUCKETS 10, starrocks_properties{replication_num: 1}, ) # --- View --- user_view View( user_view, Base.metadata, definitionSELECT id, name FROM my_core_table WHERE name IS NOT NULL, columns[ {name: id, comment: ID}, {name: name, comment: Name}, ], commentActive users, ) # --- Materialized View --- user_stats_mv MaterializedView( user_stats_mv, Base.metadata, definitionSELECT id, COUNT(*) AS cnt FROM my_core_table GROUP BY id, starrocks_refreshASYNC, )步骤 4为 autogenerate 配置env.py编辑alembic/env.py导入myapp.models以设置target_metadata导入render_column_type与include_object_for_view_mv并在run_migrations_offline()与run_migrations_online()中同时设置以便正确处理视图与物化视图、正确渲染 StarRocks 列类型。:::note 以下代码是需要在env.py中添加或修改的行而不是用整段替换生成的env.py文件。 :::from alembic import context from starrocks.alembic import render_column_type, include_object_for_view_mv from starrocks.alembic.starrocks import StarRocksImpl # noqa: F401 from myapp.models import Base target_metadata Base.metadata # Optional: set version table replication for single-BE dev clusters version_table_kwargs {starrocks_properties: {replication_num: 1}} # In both run_migrations_offline() and run_migrations_online(), ensure: def run_migrations_offline() - None: url context.config.get_main_option(sqlalchemy.url) context.configure( urlurl, target_metadatatarget_metadata, literal_bindsTrue, render_itemrender_column_type, include_objectinclude_object_for_view_mv, version_table_kwargsversion_table_kwargs, ) def run_migrations_online() - None: # ... create engine and connect as in alembic default env.py ... with connectable.connect() as connection: context.configure( connectionconnection, target_metadatatarget_metadata, render_itemrender_column_type, include_objectinclude_object_for_view_mv, version_table_kwargsversion_table_kwargs, )version_table_kwargs会被透传给StarRocksImpl.version_table_impl()见 alembic/starrocks.py这对于只有单个 BE 的开发集群非常实用——它能把版本表的副本数压到 1避免因副本数不足而创建失败。步骤 5自动生成第一个 revisionalembic revision --autogenerate -m create initial schema暂停并审查检查alembic/versions/下生成的迁移文件确认其中包含预期操作例如create_table、create_view、create_materialized_view确保没有意外的 drop 或 alter。步骤 6预览 SQL 并应用预览 SQLalembic upgrade head --sql暂停并审查确认 DDL 的执行顺序符合预期识别可能较重的操作必要时拆分迁移。应用alembic upgrade head:::important StarRocks DDL 跨多条语句不具备事务性。若升级中途失败需要检查已应用的部分并手工修复后再重新执行。 :::步骤 7修改模型并再次 autogenerate更新myapp/models.py修改既有表my_core_table新增一列或更新表 comment并修改一个表属性新增一张表my_new_table。:::note 新增列可能是耗时的 Schema 变更。StarRocks 同一时刻每张表只允许运行一个 Schema 变更任务。实践中建议将增/删/改列与其他较重变更例如更多增删列、批量属性修改分开必要时拆分成多个 Alembic revision。 :::from sqlalchemy import Column, Table from starrocks import INTEGER, VARCHAR # Modify an existing table (add a column) # (Update the existing my_core_table definition in-place.) my_core_table Table( my_core_table, Base.metadata, Column(id, INTEGER, primary_keyTrue), Column(name, VARCHAR(50)), Column(age, INTEGER), # added column only starrocks_primary_keyid, starrocks_distributed_byHASH(id) BUCKETS 10, starrocks_properties{replication_num: 1}, ) my_new_table Table( my_new_table, Base.metadata, Column(id, INTEGER, primary_keyTrue), Column(name, VARCHAR(50)), starrocks_primary_keyid, starrocks_distributed_byHASH(id) BUCKETS 10, starrocks_properties{replication_num: 1}, )alembic revision --autogenerate -m add a new table, change a old table暂停并审查确认新迁移包含针对my_new_table的create_table(...)以及针对my_core_table变更的预期操作例如 add column / set comment / set properties。预览 SQL 并应用alembic upgrade head --sql alembic upgrade head使用 sqlacodegen 反向生成模型sqlacodegen可以从 StarRocks 直接反向生成 SQLAlchemy 模型sqlacodegen --options include_dialect_options,keep_dialect_types \ --generator tables \ starrocks://user:passwordFE_host:query_port/[catalog.]database models.py支持的对象包括表Tables视图Views物化视图Materialized views分区、分布、order-by 子句以及属性Partitioning, distribution, and order-by clauses, and properties在将既有 StarRocks Schema 引入 Alembic 时这一步非常有用。你可以直接用上面的命令为端到端示例部分定义的表/视图/物化视图生成 Python 脚本。:::note 使用提示生成 Core 风格模型时建议加上--generator tablesORM 生成器可能会根据NOT NULL/NULL属性重排列顺序。Key 列可能被生成为NOT NULL如果需要它们可空请手动调整生成的模型。 :::限制与最佳实践删除重建型变更部分 StarRocks DDL 操作要求删除并重建表autogenerate 会警告或报错而不是静默生成不可用的 SQL。Key 模型变更通过ALTER TABLE修改 Key 模型例如将 DUPLICATE KEY 改为 PRIMARY KEY不受支持请制定显式方案通常是删除重建并回填数据。非事务性 DDLStarRocks 不提供跨多条语句的事务性 DDL请审查生成的迁移并谨慎执行。若迁移中途失败可能需要手动处理回滚。分布桶数分布方式中若省略BUCKETS子句StarRocks 可能自动分配桶数方言已针对该情况设计为避免产生无意义的 diff。视图与物化视图定义比较StarRocks 4.0.6旧版本集群在存储视图定义时会改写为规范形式因此模型中写的 SQL 与集群回读的 SQL 可能存在语法差异。方言通过临时视图将模型 SQL 往返取回库端规范形式后再比较。这要求模型定义引用的所有表与视图已经存在于数据库中当它们尚不存在时例如前向迁移同时创建这些对象方言回退到基于正则的规范化器它覆盖最常见的改写模式但可能无法处理所有边界情况。集群升级后的视图定义漂移如果 StarRocks 集群在视图已存在的情况下升级旧版本规范化的视图可能与升级后集群产生的逐字形式不匹配该窗口期内 autogenerate 可能产生虚假的视图迁移。重建受影响的视图drop 后重新应用迁移可解决漂移。总结借助 StarRocks SQLAlchemy 方言与 Alembic 集成你可以✔ 使用声明式模型定义 StarRocks Schema✔ 自动检测并生成 Schema 迁移脚本✔ 使用版本控制管理 Schema 演进✔ 以声明式方式管理视图与物化视图✔ 使用 sqlacodegen 反向工程既有 Schema这让 StarRocks 的 Schema 管理融入现代 Python 数据工程生态显著简化了跨环境的 Schema 一致性维护。相关参考文档均位于仓库 contrib/starrocks-python-client 中可继续深入阅读starrocks-python-client README快速开始、安装、异步用法、测试Alembic 集成指南高级过滤、日志配置、sqlacodegen 详解SQLAlchemy 使用指南Core/ORM 查询与高级特性表定义参考全部表属性与数据类型视图定义参考视图选项与限制物化视图定义参考MV 选项与 ALTER 限制【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考