oh-my-muse/muse-cloud/sql/dev/muse-slice-sequences-repair-postgres.sql
lili a5b91da7a5 fix(infra): 补 muse_slice_live 缺失的 yudao @KeySequence 命名序列(dev 环境修复工具)
slice 库建表时漏建 yudao 各模块命名序列(@KeySequence 依赖),导致 system_login_log 等表 insert 时 SELECT nextval 报序列不存在(admin login 500)、知识库摄入受阻。

新增 sql/dev/muse-slice-sequences-repair-postgres.sql:
- 序列清单=全仓 @KeySequence 扫描(92 个),与代码一致(已 diff 校验无漏无多)
- DO block:CREATE SEQUENCE IF NOT EXISTS(幂等)+ 按对应表 MAX(id) setval 对齐(避免序列从 1 起与既有数据主键冲突);表不存在或主键非 id 则只建序列、跳过对齐
- 只新增序列对象,不改表结构、不动数据,可重跑

适用命名序列版 slice 库(与 sql/dev/yudao-base-schema 的 IDENTITY 自增版策略不同,后者自洽不需此补丁)。对 muse_slice_live 执行后 public 序列 2→93,配合 muse-file-config-master-seed 打通文件存储链路(FILE_SERVICE_UNAVAILABLE 解除)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 07:57:45 -07:00

71 lines
4.3 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- muse_slice_live 缺失 yudao @KeySequence 命名序列补丁
-- ============================================================
-- 背景muse_slice_live 这个 slice 库建表时漏建 yudao 各模块的命名序列。
-- yudao 的 DO 用 @KeySequence("xxx_seq")mybatis-plus 在应用层 insert 前
-- SELECT nextval('xxx_seq') 取主键;序列不存在 → insert 报错
-- admin 登录写 system_login_log 时 system_login_log_seq 不存在 → 500
-- 来源:序列清单 = 全仓 @KeySequence 扫描92 个。muse 业务表用 IDENTITY/雪花,
-- 不依赖这些命名序列,故与本补丁无冲突(同名不会发生)。
-- 策略CREATE SEQUENCE IF NOT EXISTS幂等+ 按对应表 MAX(id) setval 对齐,
-- 避免序列从 1 起与既有数据主键冲突;表不存在或主键非 id 则只建序列、跳过对齐。
-- 安全:幂等可重跑;只新增序列对象,不改表结构、不动数据。
-- ============================================================
DO $func$
DECLARE
seq_name text;
tbl_name text;
next_id bigint;
seqs text[] := ARRAY[
'ai_api_key_seq','ai_chat_conversation_seq','ai_chat_message_seq','ai_chat_role_seq',
'ai_image_seq','ai_knowledge_document_seq','ai_knowledge_segment_seq','ai_knowledge_seq',
'ai_mind_map_seq','ai_model_seq','ai_music_seq','ai_tool_seq','ai_workflow','ai_write_seq',
'bpm_category_seq','bpm_form_seq','bpm_oa_leave_seq','bpm_process_definition_info_seq',
'bpm_process_expression_seq','bpm_process_instance_copy_seq','bpm_process_listener_seq','bpm_user_group_seq',
'infra_api_access_log_seq','infra_api_error_log_seq','infra_codegen_column_seq','infra_codegen_table_seq',
'infra_config_seq','infra_data_source_config_seq','infra_file_config_seq','infra_file_content_seq','infra_file_seq',
'member_address_seq','member_config_seq','member_experience_record_seq','member_group_seq',
'member_level_record_seq','member_level_seq','member_point_record_seq','member_sign_in_config_seq',
'member_sign_in_record_seq','member_tag_seq','member_user_seq',
'mp_account_seq','mp_auto_reply_seq','mp_material_seq','mp_menu_seq','mp_message_seq',
'mp_message_template_seq','mp_tag_seq','mp_user_seq',
'pay_app_seq','pay_channel_seq','pay_demo_order_seq','pay_demo_withdraw_seq','pay_notify_log_seq',
'pay_notify_task_seq','pay_order_extension_seq','pay_order_seq','pay_refund_seq','pay_transfer_seq',
'pay_wallet_recharge_package_seq','pay_wallet_recharge_seq','pay_wallet_seq','pay_wallet_transaction_seq',
'report_go_view_project_seq',
'system_dept_seq','system_dict_data_seq','system_dict_type_seq','system_login_log_seq',
'system_mail_account_seq','system_mail_log_seq','system_mail_template_seq','system_menu_seq',
'system_notice_seq','system_notify_message_seq','system_notify_template_seq','system_operate_log_seq',
'system_post_seq','system_role_menu_seq','system_role_seq','system_sms_channel_seq',
'system_sms_code_seq','system_sms_log_seq','system_sms_template_seq','system_social_client_seq',
'system_social_user_bind_seq','system_social_user_seq','system_tenant_package_seq','system_tenant_seq',
'system_user_post_seq','system_user_role_seq','system_users_seq'
];
BEGIN
FOREACH seq_name IN ARRAY seqs LOOP
-- 幂等建序列
EXECUTE format('CREATE SEQUENCE IF NOT EXISTS %I', seq_name);
-- 序列名去掉结尾 _seq 推断对应表ai_workflow 等无 _seq 的,表多半不存在,跳过对齐)
IF right(seq_name, 4) = '_seq' THEN
tbl_name := left(seq_name, length(seq_name) - 4);
ELSE
tbl_name := seq_name;
END IF;
-- 表存在则按 MAX(id) 对齐,避免与既有数据主键冲突
IF EXISTS (SELECT 1 FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = tbl_name) THEN
BEGIN
EXECUTE format('SELECT COALESCE(MAX(id), 0) + 1 FROM %I', tbl_name) INTO next_id;
IF next_id > 1 THEN
-- false下一次 nextval 返回 next_id 本身
EXECUTE format('SELECT setval(%L, %s, false)', seq_name, next_id);
END IF;
EXCEPTION WHEN undefined_column THEN
-- 主键非 id 列,无法自动对齐,仅保留新建序列
NULL;
END;
END IF;
END LOOP;
END
$func$;