RenameColumnOperation 深度解析:openJiuwen agent-core-java 记忆库 SQL 列重命名迁移实战
人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习【免费下载链接】agent-core-javaopenJiuwen agent core Java是 openJiuwen Core的 Java版本提供AI Agent开发、运行、调优与演进相关的全套SDK能力。项目地址https://gitcode.com/openJiuwen/agent-core-java点击查看免费下载本文围绕 openJiuwen agent-core-java 记忆迁移体系中用于 SQL 列重命名的RenameColumnOperation操作类展开先交代它在迁移计划 → 注册表 → 迁移器整体架构中的定位再逐一拆解字段、构造方法与访问器最后结合SqlMigrator源码与测试用例讲清楚列重命名在 MySQL、SQLite、H2 等不同方言下的真实执行语义与版本控制机制。读完本文你将能够为记忆库表编写一条安全、可回滚、可幂等重放的列重命名迁移操作并理解其背后的设计约束。一、类定位记忆迁移体系中的列重命名指令openJiuwen agent-core-java 的记忆memory模块在 schema 演进时会通过一套与 Python 版 openJiuwen 镜像对齐的迁移机制来调整底层存储结构。整个迁移体系由以下环节组成操作对象Operation以纯 DTO 形式描述要做一次什么变更例如新增列、重命名列、更新列类型等注册表OperationRegistry按实体表维护有序的操作链并保证版本号严格递增迁移计划MigrationPlan持有 SQL、向量库、KV 三套全局注册表迁移器Migrator读取注册表中的操作并真正执行 DDL/DML例如SqlMigrator统一入口RunMigrations启动阶段遍历注册表逐个调度迁移器。RenameColumnOperation就位于第一步它是描述把某张表的某个旧列改名为新列这一意图的数据载体。其源码类注释明确写明了镜像关系/** * pMirrors Pythons {code RenameColumnOperation} in * {code openjiuwen/core/memory/migration/operation/operations.py}./p */ public class RenameColumnOperation extends BaseOperation源码位于 RenameColumnOperation.java是纯 DTO只携带数据、不含任何执行逻辑真正的 DDL 由SqlMigrator依据它的字段动态拼装。在operation包内与它同级的操作对象还包括AddColumnOperation、UpdateColumnTypeOperation面向 SQLAddScalarFieldOperation、RenameScalarFieldOperation、UpdateScalarFieldTypeOperation、UpdateEmbeddingDimensionOperation面向向量库以及UpdateKVOperation面向 KV 存储完整清单可参见 operation.README.md。二、字段设计一条重命名操作所需的三个要素原文档对RenameColumnOperation的字段定义如下这也是该操作对象唯三的业务属性字段类型说明tableString目标表名。oldColumnNameString原列名。newColumnNameString新列名。从源码实现看这三个字段均为final在构造时一次性写入、之后不可变private final String table; private final String oldColumnName; private final String newColumnName;不可变设计保证了迁移操作对象可以在注册表、迁移器、日志等多个环节安全共享不会被意外篡改同时由于它继承自BaseOperation还额外携带一份OperationMetadata见下文第四节构成在哪里改table→ 改什么oldColumnName→ 改成什么newColumnName→ 属于哪个 schema 版本metadata的完整语义。三、构造方法与公开方法构造方法签名说明public RenameColumnOperation(OperationMetadata metadata, String table, String oldColumnName, String newColumnName)创建一条列重命名操作。四个入参对应源码构造器public RenameColumnOperation( OperationMetadata metadata, String table, String oldColumnName, String newColumnName ) { super(metadata); this.table table; this.oldColumnName oldColumnName; this.newColumnName newColumnName; }其中metadata被透传给父类BaseOperation用于标注本次操作对应的 schema 版本号与描述文本后三个参数直接写入自身字段。公开方法签名说明public String getTable()返回目标表名。public String getOldColumnName()返回旧列名。public String getNewColumnName()返回新列名。这三个访问器均返回构造时传入的原始值供SqlMigrator在执行 DDL 时读取。四、继承体系与版本元数据RenameColumnOperation继承自抽象类BaseOperation源码见 BaseOperation.java后者是所有迁移操作的公共基类统一封装元数据并提供两个版本相关入口方法行为public int getSchemaVersion()返回当前操作对应的 schema 版本号读取metadata.getSchemaVersion()。public String getDescription()返回元数据中的描述若描述为空则回退到当前类名如RenameColumnOperation。BaseOperation只有受保护的构造方法Getter注解会为metadata生成常规访问器但对外主入口仍是显式的getSchemaVersion()、getDescription()。元数据载体是OperationMetadata文档见 OperationMetadata.md它提供两个构造方法OperationMetadata(int schemaVersion, String description)同时设置版本号与描述OperationMetadata(int schemaVersion)仅设置版本号description默认为null。在典型的迁移脚本中你通常这样构造一条重命名操作RenameColumnOperation operation new RenameColumnOperation( new OperationMetadata(3, rename source column), user_message, legacy_source, source);这里的版本号3并不是随意填写的——它必须与OperationRegistry中该实体已注册操作的最大版本严格递增详见第五节。五、注册与版本控制与 OperationRegistry 的协作单个操作对象没有意义必须注册进OperationRegistry文档见 OperationRegistry.md。该注册表按实体键对应 SQL 中的表名维护MapString, ListBaseOperation并施加两条硬性规则register(String entityKey, BaseOperation op)向指定实体追加操作若版本号不大于当前最大值则抛出BaseError从源头保证同一实体的版本链严格递增getOperations(String entityKey, int fromVersion, int toVersion)按闭区间返回操作列表fromVersion toVersion时返回空列表。对于 SQL 存储全局注册表挂在MigrationPlan.SQL_REGISTRY文档见 MigrationPlan.md典型注册写法MigrationPlan.getSqlRegistry().register( user_message, new RenameColumnOperation( new OperationMetadata(3, rename source column), user_message, legacy_source, source));版本递增约束的意义在于迁移执行是按版本过滤的。SqlMigrator.tryMigrate(...)会先通过MemoryMetaManager读取memory_meta表中该表的当前schema_version只执行schemaVersion currentVersion的待办操作源码见 SqlMigrator.java。因此即使应用重启后再次触发迁移已经应用过的重命名操作也会被跳过——这正是幂等重放的保证。六、执行语义SqlMigrator 如何完成真实 DDLRenameColumnOperation本身不执行任何 SQL真正动手的是SqlMigrator文档见 SqlMigrator.md。在executeOperation(...)中迁移器通过instanceof分发到migrateRenameColumn(...)if (operation instanceof RenameColumnOperation renameColumnOperation) { migrateRenameColumn(connection, renameColumnOperation, dialectName); return; }方言差异MySQL 走 CHANGE其余走 RENAME COLUMNSqlMigrator会根据 JDBC 驱动名探测方言sqlite/h2/mysql/postgresql/unknown重命名列的拼装逻辑因方言而异源码见 SqlMigrator.javaMySQLALTER TABLE table CHANGE old new existingType。由于 MySQL 的CHANGE要求携带完整列定义迁移器会先通过DatabaseMetaData查询旧列当前的类型findColumnType如果类型查询不到则回退到标准的RENAME COLUMN语法。其他方言含 SQLite、H2、PostgreSQLALTER TABLE table RENAME COLUMN old TO new。双重安全校验在执行前SqlMigrator会对表名与列名做两重校验源码见 SqlMigrator.java表名白名单requireSupportedTable(...)要求table必须命中DbModelSupport.MEMORY_TABLES_CONFIG中的受支持记忆表否则抛出SQLException(Unsupported table name: ...)整个迁移返回false标识符合法性requireIdentifier(...)要求表名/列名匹配正则[A-Za-z_][A-Za-z0-9_]*杜绝 SQL 注入与非法标识符进入 DDL。这意味着你不能用RenameColumnOperation去改任意一张表——它只服务于记忆模块自己管理的那些表。事务与版本回写tryMigrate(...)的整体流程源码见 SqlMigrator.java若操作列表为空直接返回true从memory_meta读取当前版本过滤出待办操作若为空直接返回true关闭自动提交在单事务中依次执行所有待办操作成功后把最后一个操作的schemaVersion写回memory_metaUPDATE优先未命中则INSERT然后commit任一步失败则rollback并记录错误日志返回false。对连接的管理同样做了适配底层是DataSource时自行获取并关闭连接是现成Connection时直接复用。七、实战示例完整跑通一次列重命名迁移参考测试 SqlMigratorTest.java 中的场景一次完整的列重命名迁移可组织为import com.openjiuwen.memory.manage.mem_model.SqlDbStore; import com.openjiuwen.memory.migration.MigrationPlan; import com.openjiuwen.memory.migration.migrator.SqlMigrator; import com.openjiuwen.memory.migration.operation.OperationMetadata; import com.openjiuwen.memory.migration.operation.RenameColumnOperation; import com.openjiuwen.memory.migration.RunMigrations; // 1. 定义迁移操作user_message 表把 legacy_source 列改名为 source RenameColumnOperation rename new RenameColumnOperation( new OperationMetadata(3, rename source column), user_message, legacy_source, source); // 2. 注册进 SQL 全局注册表版本必须大于该实体当前最大版本 MigrationPlan.getSqlRegistry().register(user_message, rename); // 3. 执行迁移 SqlDbStore sqlDb new SqlDbStore(dbStore); // dbStore 为 BaseDbStoreDataSource boolean ok new SqlMigrator(sqlDb) .tryMigrate(user_message, MigrationPlan.getSqlRegistry().getOperations(user_message)) .join();也可以跳过手动构造SqlMigrator直接用统一入口RunMigrations.runSqlMigrations(sqlDbStore)文档见 RunMigrations.md它会遍历 SQL 注册表中所有实体并逐个迁移任一实体失败则返回false。一次迁移中可以混合多种操作并按版本号排序执行例如先加列、再重命名版本 1→2→3MigrationPlan.getSqlRegistry().register(user_message, new AddColumnOperation(new OperationMetadata(1, add old column), user_message, old_name, String)); MigrationPlan.getSqlRegistry().register(user_message, new RenameColumnOperation(new OperationMetadata(2, rename old column), user_message, old_name, new_name));SqlMigrator会按列表顺序在同一个事务内依次执行最终把memory_meta中user_message的版本推进到2。八、测试验证行为如何被证明仓库中针对该操作有两处直接测试证据SqlMigratorTest.tryMigrateRenamesColumnSqlMigratorTest.java先手工ALTER TABLE user_message ADD COLUMN legacy_source再以版本 3 构造RenameColumnOperation并执行断言旧列legacy_source不存在、新列source存在、memory_meta中版本变为3SqlMigratorParityTest.assertRenameColumnOperationSqlMigratorParityTest.java在一次tryMigrate调用内混入AddColumnOperation版本 1与RenameColumnOperation版本 2断言重命名生效且版本推进到2同文件的assertMultipleOperationsSqlMigratorParityTest.java还验证了col1 → col1_renamed的连续迁移场景。此外SqlMigratorParityTest.assertUnsupportedTableReturnsFalseSqlMigratorParityTest.java验证了把RenameColumnOperation用在unsupported_table上会返回false印证了表名白名单校验的存在。九、使用约束与最佳实践小结综合文档与源码使用RenameColumnOperation时有以下几点值得注意只改受支持的记忆表table必须属于DbModelSupport.MEMORY_TABLES_CONFIG列出的记忆表如user_message、scope_user_mapping非法表名会导致迁移失败并返回false标识符必须合规表名与新旧列名需匹配[A-Za-z_][A-Za-z0-9_]*不允许空格、连字符等非法字符版本号严格递增注册时OperationMetadata.schemaVersion必须大于该实体已注册的最大版本否则抛出BaseError这也是迁移可幂等重放的基础方言差异由迁移器自动处理MySQL 下自动选用CHANGE old new type必要时查询原列类型其余数据库使用标准RENAME COLUMN调用方无需关心底层语法事务保证单次tryMigrate中的全部操作在同一事务内执行成功统一提交并回写memory_meta版本失败统一回滚避免出现列改了但版本没记的中间状态。作为记忆 schema 演进的原子指令之一RenameColumnOperation的价值在于把一次数据库列改名从手写 SQL 的偶发操作变成有版本、有校验、可回滚、可重放的受控迁移让 Agent 长期运行过程中记忆表结构的平滑演进有了工程化保障。赞分享人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习【免费下载链接】agent-core-javaopenJiuwen agent core Java是 openJiuwen Core的 Java版本提供AI Agent开发、运行、调优与演进相关的全套SDK能力。项目地址https://gitcode.com/openJiuwen/agent-core-java点击查看免费下载相关推荐Java 命名规范实战openJiuwen agent-core-java 代码库中的 G.NAM 规则解读Java 命名规范实战openJiuwen agent core java 代码库中的 G.NAM 规则解读 命名是 Java 代码可读性的第一道防线。本文基人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习openJiuwen agent-core 记忆配置模块完全指南MemoryEngineConfig / MemoryScopeConfig / AgentMemoryConfig 深度解析openJiuwen agent core 记忆配置模块完全指南MemoryEngineConfig / MemoryScopeConfig / AgentM人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习openJiuwen agent-core Context Evolver 实战指南ACE / ReasoningBank / ReMe 记忆算法与记忆增强 Agent 构建openJiuwen agent core Context Evolver 实战指南ACE / ReasoningBank / ReMe 记忆算法与记忆增强人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考