You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DBUP脚本执行顺序异常求助:目录排序规则未生效

DBUP脚本执行顺序异常问题

我正在试用DBUP,但无法使其正常工作。我将脚本拆分到不同目录中,并为目录添加了数字前缀以指定执行顺序。据我了解,DBUP应先按字典序处理目录,再处理目录内的文件,但实际并非如此——它似乎将所有文件视为在同一目录中,仅按文件名字典序执行,导致数据脚本尝试向尚未创建的表插入数据。

我的代码如下:

var upgrader = DeployChanges.To.SqlDatabase(connectionString)
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "00-PreDeployment"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "01-Tables"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "02-Views"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "03-Functions"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "04-StoredProcedures"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "05-Data"))
                               .JournalToSqlTable("dbo", "SchemaVersion")
                               .LogToConsole()
                               .Build();

例如:01-Tables目录下的Statuses.sql负责创建Status表,05-Data目录下的Add_Status.sql负责填充该表。我预期先执行Statuses.sql再执行Add_Status.sql,但实际Add_Status.sql因文件名以'A'开头,比'S'开头的Statuses.sql先执行,导致表未创建就插入数据。请问我是否遗漏了配置?难道只能给所有脚本添加目录顺序前缀来解决?


解决方案

DBUP默认会把所有通过WithScriptsFromFileSystem添加的脚本合并到一个集合中,然后仅按文件名的字典序排序,不会保留目录的执行优先级——这就是问题的核心原因。

你有两种更优的解决方式,无需给每个脚本添加前缀:

1. 自定义脚本排序规则

使用WithScriptsSortedBy方法指定排序逻辑,让脚本先按所在目录的名称排序,再按文件名排序,确保目录的数字前缀先生效。修改后的代码如下:

var upgrader = DeployChanges.To.SqlDatabase(connectionString)
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "00-PreDeployment"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "01-Tables"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "02-Views"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "03-Functions"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "04-StoredProcedures"))
                               .WithScriptsFromFileSystem(Path.Combine(dbScripts, "05-Data"))
                               // 先按目录名排序,再按文件名排序
                               .WithScriptsSortedBy(script => $"{Path.GetDirectoryName(script.Path)}_{script.Name}")
                               .JournalToSqlTable("dbo", "SchemaVersion")
                               .LogToConsole()
                               .Build();

2. 按目录分批执行升级

如果需要严格保证前一个目录的所有脚本执行完成后,再执行下一个目录的脚本,可以拆分升级逻辑,分批次执行:

// 执行预部署脚本
var preDeployUpgrader = DeployChanges.To.SqlDatabase(connectionString)
    .WithScriptsFromFileSystem(Path.Combine(dbScripts, "00-PreDeployment"))
    .JournalToSqlTable("dbo", "SchemaVersion")
    .LogToConsole()
    .Build();
var preDeployResult = preDeployUpgrader.PerformUpgrade();
if (!preDeployResult.Successful)
{
    // 处理失败逻辑,比如输出错误信息并终止
    Console.WriteLine(preDeployResult.Error);
    return;
}

// 执行表脚本
var tablesUpgrader = DeployChanges.To.SqlDatabase(connectionString)
    .WithScriptsFromFileSystem(Path.Combine(dbScripts, "01-Tables"))
    .JournalToSqlTable("dbo", "SchemaVersion")
    .LogToConsole()
    .Build();
var tablesResult = tablesUpgrader.PerformUpgrade();
if (!tablesResult.Successful)
{
    Console.WriteLine(tablesResult.Error);
    return;
}

// 依次执行视图、函数、存储过程、数据脚本的升级
// 代码逻辑与上述示例一致

这种方式完全保证了目录的执行顺序,适合对脚本执行先后有严格要求的场景。

内容的提问来源于stack exchange,提问作者Jack Thor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:01:28