我正在尝试使用Liquibase将一个数据库转换为另一个数据库。我有两个数据库,希望在其中一个数据库上运行SQL脚本,使其与另一个数据库相同。我正在使用Liquibase版本3.4.1和两个H2数据库。为了生成SQL脚本,我首先使用diffChangeLog命令生成diff xml,该命令运行良好。(实际上有一个问题:它生成的列类型为VARCHAR,autoIncrement设置为true,但可以手动删除)。然后,我使用命令updateSQL从diff-xml生成SQL文件。SQL文件包含以下行:
ALTER TABLE PUBLIC.USERS ADD ENABLED BOOLEAN(1) NOT NULL;
最初,db包含一个名为USERS的表,该表有两列:USER和PASSWORD,其中有一行数据(user1,密码)。SQL脚本此时失败,因为它试图创建一个新列,该列的第一行条目将设置为NULL,但该列应该不是NULL。错误是:
错误:“ENABLED”列不允许为NULL;
SQL语句:ALTER TABLE PUBLIC. USERS ADD ENABLED BOOLEAN(1)Not NULL
[23502-187]
SQLState:23502
错误代码:23502
错误发生在:ALTER TABLE PUBLIC。用户添加启用的布尔值(1)非空
我可以尝试手动删除NOT NULL条件,但这并不是在下面描述的所有情况下都有效。当我删除NOT NULL时,会发生以下情况:
执行以下行时(就在上面一行之后)会发生另一个相关错误:
ALTER TABLE PUBLIC.USERS ADD USERNAME VARCHAR(50) NOT NULL;
注意,它试图添加“USERNAME”列,而不是原始数据库中已有的“USER”列。
它会产生相同的错误,当我删除NOT NULL时,会出现另一个错误:
错误:“用户名”列不能为空;
SQL语句:
ALTER TABLE PUBLIC。用户添加CONSTRAINT CONSTRAINT_4主键(用户名)
[90023-187]
SQLState:90023
错误代码:90023
错误发生在:
ALTER TABLE PUBLIC。用户添加CONSTRAINT CONSTRAINT_4主键(用户名)
由于该列是主键,因此它不能为空。
有没有一种方法可以轻松解决这个问题?Liquibase中是否有一个选项可以消除这些错误?
这取决于您的数据库。MySQL/Mariadb可以很简单:
<changeSet author="tibi" id="201803062100-1">
<addColumn tableName="jhi_user">
<column name="status" type="varchar(20)" value="ENABLED" />
<constraints nullable="false" />
</addColumn>
</changeSet>
H2不允许这样做,因此您需要:
<changeSet author="tibi" id="201803062100-1">
<addColumn tableName="jhi_user">
<column name="status" type="varchar(20)" value="ENABLED" />
</addColumn>
<addNotNullConstraint columnDataType="varchar(20)" columnName="status" tableName="jhi_user" />
</changeSet>
或者针对您的情况:
<changeSet author="tibi" id="201803062100-1">
<addColumn tableName="jhi_user">
<column name="status" type="boolean" value="0" />
</addColumn>
<addNotNullConstraint columnDataType="boolean" columnName="status" tableName="jhi_user" />
</changeSet>
当您添加一个非空列时,技巧是给它一个默认值。在Liquibase XML中,对于列定义,您需要这样的内容:
<column
name="ENABLED"
type="BOOLEAN(1)"
defaultValue="0"
>
这应该生成一个默认为0的NOT NULL子句,适用于平台。
首先添加列,不带NOT NULL设置。然后更新现有行的列。最后,应用NOT NULL约束。
<addNotNullConstraint catalogName="cat"
columnDataType="int"
columnName="id"
defaultNullValue="A String"
schemaName="public"
tableName="person"/>
我不建议使用defaultValue设置,因为如果您的行数较高,它可能会锁定表。对生产中的维护窗口非常不利。
目标: 需要向现有的Debezium MySQL连接器版本1.1.1添加一个新表。最终的连接器重新启动后,应使用更新的配置(table.whitelist中的新表)将表中的数据填充到主题中。 问题: 没有明确的策略来添加一个新表,该表将在初始快照完成后(连接器的前一个版本正在工作)与其数据一起添加到Kafka中。我们正在寻找类似于snapshot.select.statement.override
问题内容: 我有一个表,其中的列包含一些空值。我想在该列上添加约束,而不将现有的null更新为非null值。我想保留现有的空值,并检查将来的行,它们是否包含此列的非空值。这可能吗?如何? 问题答案: 您可以添加未验证的约束-它不会查看现有行,但是会检查是否有任何新行或更新行。 请注意,除非满足约束,否则您将无法更新现有行。 另外,请注意,不利之处在于,优化器在制定计划时将无法利用此约束-它必须假设
问题内容: 我正在显示此示例产品表。我需要在不使用结果集的情况下将所有表日期合并到一个jsp中。我尝试完成这一部分: 我需要将所有表数据添加到列表或?? 并使用方法将其退回我该怎么办? 问题答案: 使您的方法返回a 而不是单个。 然后,在您的JSP文件中,迭代返回的列表:
很容易将列表列表转换为数据帧: 但是我如何将df转换回列表列表呢?
问题内容: 与此问题类似,如何将空列添加到数据框?,我想知道向DataFrame添加一列空列表的最佳方法。 我想要做的基本上是初始化一列,然后遍历行以处理其中的一些行,然后在此新列中添加填充列表以替换初始化的值。 例如,如果下面是我的初始DataFrame: 然后,我最终希望得到这样的结果,其中每一行都经过单独处理(显示了示例结果): 当然,如果我尝试像使用其他任何常量一样进行初始化,它会认为我正
问题内容: 我试图基于一个的数据创建“ n” 。我正在检查in的Integer值,并循环执行sql语句以创建与列中一样多的“ n” 。 这是我的代码: 我需要创建“ n”,但我不知道如何在循环之前声明类型并在for内填充。 现有数据类型: 新的数据类型: 问题答案: 您可以创建一个可变列表并填充它: 但是更好的方法(不使用可变数据结构)是将整数列表 映射 到DataFrames列表中: