gpt4 book ai didi

NHibernate 数据库版本控制 : object level schema and data upgrades

转载 作者:行者123 更新时间:2023-12-02 05:37:41 26 4
gpt4 key购买 nike

我想在 NHibernate 中从与大多数策略不同的方向处理数据库版本控制和自动升级。

由于每个对象都是由 XML 映射定义的,我想获取每个映射文件/配置的大小和校验和,并将其与潜在的自定义更新脚本一起存储在文档数据库(raven 或其他)中。如果未找到脚本,请使用 NHibernate DDL 生成器更新对象架构。这样我就可以检测到变化,如果除了 DDL 之外还需要进行 DML 更改,或者执行精心排序的转换,理论上我可以以可控、可测试的方式进行。这也应该保持一定程度的持久层不可知论,尽管我认为脚本仍然必须是特定于数据库系统的。

诀窍是从数据库中生成“旧”映射文件并将它们与当前映射文件进行比较。我不知道这是否可能。我也不知道我是否遗漏了任何其他会使该策略极其不切实际的东西。

那么我的问题是:这个策略的实用性如何,为什么?

最佳答案

我做了什么来解决那个问题

  1. 在名为 SchemaVersion 的表中对数据库进行版本控制
  2. 查询表以查看模式是否是最新的(所需版本存储在 DAL 中),如果是则转到 6。
  3. 从 resources/webservices/...获取版本 == versionFromBb 的更新脚本<​​/li>
  4. 运行脚本,同时将 schemaversion 更改为新版本
  5. 转到 2.
  6. 运行应用

为了生成脚本,我使用了 2 个选项

  1. 支持一个rdbms:运行SchemaUpdate导出到文件并手动添加DML语句
  2. 支持多个 rdbms:使用 Nhibernate 类 Table 在运行时生成 ddl 以添加/更改/删除表和使用 session DML 的代码

更新:

"what method did you use to store the current version"

small example

像这样

public static class Constants
{
public static readonly Version DatabaseSchemaVersion = new Version(1, 2, 3, 4);
}

public class DBMigration
{
private IDictionary<Version, Action> _updates = new Dictionary<Version, Action>();
private Configuration _config;
private Dialect _dialect;
private IList<Action<ISession>> _actions = new List<Action<ISession>>(16);
private string _defaultCatalog;
private string _defaultSchema;

private void CreateTable(string name, Action<Table> configuretable)
{
var table = new Table(name);
configuretable(table);

string createTable = table.SqlCreateString(_dialect, _config.BuildMapping(), _defaultCatalog, _defaultSchema);
_actions.Add(session => session.CreateSQLQuery(createTable).ExecuteUpdate());
}

private void UpdateVersionTo(Version version)
{
_actions.Add(session => { session.Get<SchemaVersion>(1).Value = version; session.Flush(); });
}

private void WithSession(Action<session> action)
{
_actions.Add(action);
}

public void Execute(Configuration config)
{
_actions.Clear();
_defaultCatalog = config.Properties[NH.Environment.DefaultCatalog];
_defaultSchema = config.Properties[NH.Environment.DefaultSchema];
_config = config;
_dialect = Dialect.GetDialect(config.Properties);

using (var sf = _config.BuildSessionFactory())
using (var session = sf.OpenSession())
using (var tx = session.BeginTransaction())
{
Version dbVersion = session.Get<SchemaVersion>(1).Value;
while (dbVersion < Constants.DatabaseSchemaVersion)
{
_actions.Clear();
_updates[dbVersion].Invoke(); // init migration, TODO: error handling
foreach (var action in _actions)
{
action.Invoke(session);
}
tx.Commit();
session.Clear();
dbVersion = session.Get<SchemaVersion>(1).Value;
}
}
}

public DBMigration()
{
_updates.Add(new Version(1, 0, 0, 0), UpdateFromVersion1);
_updates.Add(new Version(1, 0, 1, 0), UpdateFromVersion1);
...
}

private void UpdateFromVersion1()
{
AddTable("Users", table => table.AddColumn(...));
WithSession(session => session.CreateSqlQuery("INSERT INTO ..."));
UpdateVersionTo(new Version(1,0,1,0));
}

...
}

关于NHibernate 数据库版本控制 : object level schema and data upgrades,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11434351/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com