【问题标题】:What's a good way (or tool) to version control a SQLite database (schema only)?什么是版本控制 SQLite 数据库(仅模式)的好方法(或工具)?
【发布时间】:2015-11-19 16:54:57
【问题描述】:

任何人都可以提出一个好的方法(或工具)来控制 SQLite 数据库(仅模式)吗?我正在尝试对 SQLite 数据库进行版本控制,我能找到的唯一选择是使用 GIT 对整个文件进行版本控制,但我现在对数据不感兴趣,只是架构发生了变化。

有什么建议吗?

谢谢:-)

【问题讨论】:

  • 您是在尝试跟踪更改以进行开发,还是您尝试将其合并到应用程序中?
  • 我正在尝试跟踪开发变化。试图找到与 Redgate 的 SQL 源代码控制工具非常相似的东西。

标签: sql database sqlite version-control windows-7


【解决方案1】:

我有两个答案。如果您的 sqlite 足够轻巧且不经常更新,则可以将其添加到存储库中而不会产生太多影响/问题。

但差异的可读性下降,因为它是作为二进制存储的。

sqlite3 git 差异

这里是如何让 git 很好地显示差异:

https://gist.github.com/peteristhegreat/a028bc3b588baaea09ff67f405af2909

git config diff.sqlite3.textconv 'sqlite3 $1 .dump'
echo '*.db diff=sqlite3' >> $(git rev-parse --show-toplevel)/.gitattributes

现在,当您的 sqlite db 文件更改时,您可以通过 git diff 看到更改。

如果您只想查看架构的差异,只需将.dump 更改为.schema,它应该只执行创建调用并跳过插入。

使用 clean/smudge 进出存储库的 sqlite3 转换

如果您希望您的 db 文件以 sql 而不是 db 的形式推送到存储库中,您可以使用 git 中的 clean/smudge 机制。

https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Keyword-Expansion

https://github.com/gilesbowkett/git-smudge-and-clean

我还没有尝试过,但基本上每当您遇到一个 db 文件时,git 都会使用 sqlite3 $1 .schema 导出提交文件的精简版本(作为 sql 命令)。然后,当您从数据库中签出该文件时,它会使用cat $1 | sqlite3 转换回数据库。

sqlite3 始终保持最新文件

Right way of tracking a sqlite3 binary file in git?

.gitattributes

mysqlite3.db merge=keepTheir

希望对您有所帮助。

【讨论】:

  • 在我的设置中,git diff 给出了错误Error: near "/": syntax error fatal: unable to read files to diff。修复方法是将 sqlite3 $1 .dump 移动到单独的 shell 脚本并从 textconv 设置中引用它。
  • 听起来您有权限问题或文件不存在。你试过只输入sqlite path/to/filename.db .dump
  • 与@Eero 相同的问题。这有效:git config diff.sqlite3.textconv 'f() { sqlite3 "$@" .dump; }; f'
【解决方案2】:

SQLite.org 上的here 此处记录了一个名为 sqldiff.exe 的命令行实用程序。它提供了各种选项,包括比较模式。要将 git 配置为使用 sqldiff 而不是内置的 diff 工具,请查看此讨论:How do I view 'git diff' output with a visual diff program?。不幸的是,它看起来不是一项微不足道的任务。

编辑: 看来获取 sqldiff 工具的唯一方法是下载完整源代码(一直在下载页面的底部)并进行编译。

【讨论】:

  • 感谢您的建议,不幸的是,sqldiff“(当前)不显示触发器、视图的差异......”。我还有几个需要版本控制。
【解决方案3】:

FWIW,我一直在使用下面摘录的 Makefile 在 Git 中跟踪一个 13MB / 20k 行的 SQLite 数据库。两个文件,schema.sqldata.sql 存储在 Git 中,通常可以将 diff 编辑为文本文件。


SQLITE=sqlite3
SCHEMAFILE=schema.sql
DATAFILE=data.sql
DBFILE=my_database.db
TEMPDB=temp.db

dump: $(DBFILE)
    @$(SQLITE) $(DBFILE) .sha3sum >sha3_before
    $(SQLITE) $(DBFILE) ".schema --indent" | grep -v sqlite_sequence >$(SCHEMAFILE)
    $(SQLITE) $(DBFILE) .dump | grep ^INSERT | grep -v sqlite_sequence >$(DATAFILE)
    @rm -f $(TEMPDB)
    @cat $(SCHEMAFILE) $(DATAFILE) | $(SQLITE) $(TEMPDB)
    @$(SQLITE) $(TEMPDB) .sha3sum >sha3_after
    @cmp sha3_before sha3_after
    @rm sha3_before sha3_after
    @rm $(TEMPDB)

database:
    rm -f $(DBFILE)
    cat $(SCHEMAFILE) $(DATAFILE) | $(SQLITE) $(DBFILE)

dump 步骤生成新的schema.sqldata.sql 文件,然后从中生成一个新数据库,并比较数据库前后的 SQLite .sha3sum 以验证它是否获得了准确的副本。

在我的应用程序中,此数据库用作只读.db 文件(本质上是产品目录),因此它具有单一更新源。我的更新周期是:

   make database
   # update the data in the database as needed
   make dump
   git commmit schema.sql data.sql

我在这个过程中遇到的唯一问题是.schema 命令有时会在我每次生成它时在CREATE VIEW ... 语句之后添加一个格式化的注释字段,并且不会删除旧的。因此,我的schema.sql 文件中的 cmets 逐渐增加。我通过查看 git diff 并在提交前手动调整来缓解这种情况。

【讨论】:

    【解决方案4】:

    从 sqlite 文档中,您可以从 sqlite_master 隐藏表中提取架构信息。 (https://www.sqlite.org/fileformat2.html#sqlite_master)

    您可以将此内容保存在 GIT 中的文本文件中,这应该为您提供一种跟踪架构更改的方法。

    【讨论】:

      猜你喜欢
      • 2022-10-04
      • 1970-01-01
      • 2010-10-10
      • 2010-10-11
      • 2012-01-21
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      相关资源
      最近更新 更多