如何使用liquibase自动生成变更集的ID?
我不想手动设置每个变更集的ID,有没有办法自动完成?
答案 0 :(得分:1)
我不认为生成的ID是个好主意。原因是liquibase使用changeSet id来计算校验和(除了author和fileName)。因此,如果您在其他人之间插入changeSet,则所有后续changeSet的校验和将发生变化,您将收到大量警告/错误。
无论如何,如果您仍想生成ID,我可以想到这些解决方案:
如果您自己解析ChangeLog,则可以根据需要自由生成ID。 缺点是您必须为changeLog提供自定义Xml架构。 Liquibase的模式对changeSet ids(必需)有约束。使用新架构,您可能需要对解析器进行大量调整。 或者,您可以选择另一种changeLog格式(YAML,JSON,Groovy)。他们的解析器可能更容易定制,因为他们不需要该模式定义。
您可以编写一个简单的xslt(Xml转换),它从没有的文件生成带有changeSet ID的changeLog。
这是我的建议。它没有按您提出的方式解决问题,但它简单,一致,提供了额外的信息,对于其他数据库迁移工具也是一种很好的做法http://www.jeremyjarrell.com/using-flyway-db-with-distributed-version-control/
答案 1 :(得分:1)
我编写了一个Python脚本,以在Liquibase更改日志中生成唯一的ID。
小心!
DO生成ID
不生成ID -更改日志已部署时
"""
###############################################################################
Purpose: Generate unique subsequent IDs into Liquibase changelogs
###############################################################################
Args:
param1: Full Windows path changelog directory (optional)
OR
--inplace: directly process changelogs (optional)
By default, XML files in the current directory are processed.
Returns:
In case of success, the output path is returned to stdout.
Otherwise, we crash and drag the system into mordor.
If you feel like wasting time you can:
a) port path handling to *nix
b) handle any obscure exceptions
c) add Unicode support (for better entertainment)
Dependencies:
Besides Python 3, in order to preserve XML comments, I had to use lxml
instead of the stock ElementTree parser.
Install lxml:
$ pip install lxml
Proxy clusterfuck? Don't panic! Simply download a .whl package from:
https://pypi.org/project/lxml/#files and install with pip.
Bugs:
Changesets having id="0" are ignored. Usually, these do not occur.
Author:
Tobias Bräutigam
Versions:
0.0.1 - re based, deprecated
0.0.2 - parse XML with lxml, CURRENT
"""
import datetime
import sys
import os
from pathlib import Path, PureWindowsPath
try:
import lxml.etree as ET
except ImportError as error:
print ('''
Error: module lxml is missing.
Please install it:
pip install lxml
''')
exit()
# Process arguments
prefix = '' # hold separator, if needed
outdir = 'out'
try: sys.argv[1]
except: pass
else:
if sys.argv[1] == '--inplace':
outdir = ''
else:
prefix = outdir + '//'
# accept Windows path syntax
inpath = PureWindowsPath(sys.argv[1])
# convert path format
inpath = Path(inpath)
os.chdir(inpath)
try: os.mkdir(outdir)
except: pass
filelist = [ f for f in os.listdir(outdir) ]
for f in filelist: os.remove(os.path.join(outdir, f))
# Parse XML, generate IDs, write file
def parseX(filename,prefix):
cnt = 0
print (filename)
tree = ET.parse(filename)
for node in tree.getiterator():
if int(node.attrib.get('id', 0)):
now = datetime.datetime.now()
node.attrib['id'] = str(int(now.strftime("%H%M%S%f"))+cnt*37)
cnt = cnt + 1
root = tree.getroot()
# NS URL element name is '' for Etree, lxml requires at least one character
ET.register_namespace('x', u'http://www.liquibase.org/xml/ns/dbchangelog')
tree = ET.ElementTree(root)
tree.write(prefix + filename, encoding='utf-8', xml_declaration=True)
print(str(cnt) +' ID(s) generated.')
# Process files
print('\n')
items = 0
for infile in os.listdir('.'):
if (infile.lower().endswith('.xml')) == True:
parseX(infile,prefix)
items=items+1
# Message
print('\n' + str(items) + ' file(s) processed.\n\n')
if items > 0:
print('Output was written to: \n\n')
print(str(os.getcwd()) + '\\' + outdir + '\n')