强制 DBUP 在开发过程中重新运行新脚本
Force DBUP to rerun new scripts during development
我们正在使用 DBUP 来处理数据库迁移。每个版本,我们都希望 运行 带有命令行开关的 dbup 控制台应用程序,以便在开发期间我们可以在我们处理脚本时重新 运行 我们的脚本,但是我们不希望它重新 运行 所有已经出现在数据库中的以前版本的脚本。如何实现?
我们向 DbUp 控制台应用程序添加了“-debug”命令行开关。如果存在,我们会在与数据库对话时切换使用哪个 Journal class。
DbUp中的Journal class (https://dbup.readthedocs.io/en/latest/more-info/journaling/)是与数据库交互的class,用于检查记录哪些脚本已经运行(由架构版本中的默认设置 table)。对于 Dev,我们强制使用它的只读版本,它可以检查哪些脚本已经存在(以防止你每次都重新 运行ning everything)但会阻止记录新记录,以便下次它会尝试重新运行您的新脚本。
只读日志看起来像这样;
public class ReadOnlyJournal : IJournal
{
private readonly IJournal _innerJournal;
public ReadOnlyJournal(IJournal innerJournal)
{
_innerJournal = innerJournal;
}
public void EnsureTableExistsAndIsLatestVersion(Func<IDbCommand> dbCommandFactory)
{
_innerJournal.EnsureTableExistsAndIsLatestVersion(dbCommandFactory);
}
public string[] GetExecutedScripts()
{
return _innerJournal.GetExecutedScripts().ToArray();
}
public void StoreExecutedScript(SqlScript script, Func<IDbCommand> dbCommandFactory)
{
// don't store anything
}
}
然后是一个扩展方法,可以更轻松地指定这个新期刊的使用;
public static class DbUpHelper
{
public static UpgradeEngineBuilder WithReadOnlyJournal(this UpgradeEngineBuilder builder, string schema, string table)
{
builder.Configure(c => c.Journal = new ReadOnlyJournal(new SqlTableJournal(() => c.ConnectionManager, () => c.Log, schema, table)));
return builder;
}
}
最后是对 DbUp 控制台应用程序的更改;
var upgrader = debug
? DeployChanges.To
.SqlDatabase(connectionString)
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
.WithReadOnlyJournal("dbo", "SchemaVersions")
.LogToConsole()
.Build()
: DeployChanges.To
.SqlDatabase(connectionString)
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
.LogToConsole()
.Build();
var result = upgrader.PerformUpgrade();
if (!result.Successful)
....
我们正在使用 DBUP 来处理数据库迁移。每个版本,我们都希望 运行 带有命令行开关的 dbup 控制台应用程序,以便在开发期间我们可以在我们处理脚本时重新 运行 我们的脚本,但是我们不希望它重新 运行 所有已经出现在数据库中的以前版本的脚本。如何实现?
我们向 DbUp 控制台应用程序添加了“-debug”命令行开关。如果存在,我们会在与数据库对话时切换使用哪个 Journal class。
DbUp中的Journal class (https://dbup.readthedocs.io/en/latest/more-info/journaling/)是与数据库交互的class,用于检查记录哪些脚本已经运行(由架构版本中的默认设置 table)。对于 Dev,我们强制使用它的只读版本,它可以检查哪些脚本已经存在(以防止你每次都重新 运行ning everything)但会阻止记录新记录,以便下次它会尝试重新运行您的新脚本。
只读日志看起来像这样;
public class ReadOnlyJournal : IJournal
{
private readonly IJournal _innerJournal;
public ReadOnlyJournal(IJournal innerJournal)
{
_innerJournal = innerJournal;
}
public void EnsureTableExistsAndIsLatestVersion(Func<IDbCommand> dbCommandFactory)
{
_innerJournal.EnsureTableExistsAndIsLatestVersion(dbCommandFactory);
}
public string[] GetExecutedScripts()
{
return _innerJournal.GetExecutedScripts().ToArray();
}
public void StoreExecutedScript(SqlScript script, Func<IDbCommand> dbCommandFactory)
{
// don't store anything
}
}
然后是一个扩展方法,可以更轻松地指定这个新期刊的使用;
public static class DbUpHelper
{
public static UpgradeEngineBuilder WithReadOnlyJournal(this UpgradeEngineBuilder builder, string schema, string table)
{
builder.Configure(c => c.Journal = new ReadOnlyJournal(new SqlTableJournal(() => c.ConnectionManager, () => c.Log, schema, table)));
return builder;
}
}
最后是对 DbUp 控制台应用程序的更改;
var upgrader = debug
? DeployChanges.To
.SqlDatabase(connectionString)
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
.WithReadOnlyJournal("dbo", "SchemaVersions")
.LogToConsole()
.Build()
: DeployChanges.To
.SqlDatabase(connectionString)
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
.LogToConsole()
.Build();
var result = upgrader.PerformUpgrade();
if (!result.Successful)
....