Databricks Delta table 十进制(10,0)到十进制(38,18)转换的更改列不起作用
Databricks Delta table Alter column for decimal(10,0) to decimal(38,18) conversion not working
在 Databricks 中,table 是使用架构 json 定义创建的。
架构 json 用于创建 table
{
"fields": [
{
"metadata": {},
"name": "username",
"nullable": true,
"type": "string"
},
{
"metadata": {},
"name": "department",
"nullable": true,
"type": "string"
},
{
"metadata": {},
"name": "income",
"nullable": true,
"type": "decimal(38,18)"
}
],
"type" :"struct"
}
下面的代码创建 table
...
# the schema json file is placed in a location and using it to create table
with open('/dbfs/FileStore/my-schema/{0}.json'.format(tbl_name), 'r') as f:
# data files
tbl_schema = T.StructType.fromJson(json.loads(f.read()))
tbl_df = spark.createDataFrame([], tbl_schema)
tbl_df.write.format("delta").save(tbl_path)
# create table.
spark.sql("CREATE TABLE {0} USING DELTA LOCATION '{1}'".format(tbl_name, tbl_path))
...
当我 describe
table 时,我看到收入字段的 DecimalType(10,0)。
我正在使用读取流从 ORC 文件中读取数据,其中使用 Decimal(38,18),能够在数据帧中打印 Scehma()。
我正在使用 Spark 结构化流写入流,它使用 UPSERT(合并到),使用 foreachBatch()。
类似于此 link https://docs.azuredatabricks.net/_static/notebooks/merge-in-streaming.html
中的 python 示例
问题:
每当我 运行 时 table 没有插入数据。也没有调试日志消息。
我想这个问题可能是由于 table 中的字段收入是 DecimalType(10,0),而数据帧是 DecimalType(38,18)。
所以我正在尝试改变字段,但无法做到。我正在使用以下命令。
%sql ALTER TABLE mytable ALTER income TYPE decimal(38,18);
com.databricks.backend.common.rpc.DatabricksExceptions$SQLExecutionException: org.apache.spark.sql.AnalysisException: ALTER TABLE CHANGE COLUMN is not supported for changing column 'income' with type 'DecimalType(10,0) (nullable = true)' to 'income' with type 'DecimalType(38,18) (nullable = true)'
at com.databricks.sql.transaction.tahoe.DeltaErrors$.alterTableChangeColumnException(DeltaErrors.scala:478)
at com.databricks.sql.transaction.tahoe.commands.AlterTableChangeColumnDeltaCommand.verifyColumnChange(alterDeltaTableCommands.scala:412)
at com.databricks.sql.transaction.tahoe.commands.AlterTableChangeColumnDeltaCommand.$anonfun$run(alterDeltaTableCommands.scala:295)
at com.databricks.sql.transaction.tahoe.schema.SchemaUtils$.transform(SchemaUtils.scala:762)
at com.databricks.sql.transaction.tahoe.schema.SchemaUtils$.transformColumnsStructs(SchemaUtils.scala:781)
at com.databricks.sql.transaction.tahoe.commands.AlterTableChangeColumnDeltaCommand.$anonfun$run(alterDeltaTableCommands.scala:292)
at com.databricks.spark.util.FrameProfiler$.record(FrameProfiler.scala:80)
at com.databricks.sql.transaction.tahoe.metering.DeltaLogging.$anonfun$recordDeltaOperation(DeltaLogging.scala:122
如果我删除 TYPE ,我会得到下面的异常
com.databricks.backend.common.rpc.DatabricksExceptions$SQLExecutionException: org.apache.spark.sql.catalyst.parser.ParseException:
mismatched input 'decimal' expecting {<EOF>, ';'}(line 1, pos 46)
== SQL ==
ALTER TABLE ahm_db.message_raw ALTER income decimal(38,18)
----------------------------------------------^^^
at org.apache.spark.sql.catalyst.parser.ParseException.withCommand(ParseDriver.scala:265)
at org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parse(ParseDriver.scala:134)
at org.apache.spark.sql.execution.SparkSqlParser.parse(SparkSqlParser.scala:64)
at org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parsePlan(ParseDriver.scala:85)
at com.databricks.sql.parser.DatabricksSqlParser.$anonfun$parsePlan(DatabricksSqlParser.scala:67)
at com.databricks.sql.parser.DatabricksSqlParser.parse(DatabricksSqlParser.scala:87)
因为在我的例子中是 delta lake store,所以启用了 options('checkpoint','/_checkpoint')
选项。数据参考仍然可用。
在开发过程中,删除 table 并使用 vaccum 优化后。
%sql delete from <my-table-name>
spark.conf.set('spark.databricks.delta.retentionDurationCheck.enabled','false')
# use spark.conf.get('property') to check default or current value
# Per documentation setting retention duration less than 7 days is not a recommended practice, but depends on requirements
%sql
VACUUM <my-table-name> RETAIN 0 HOURS
%sql
drop table <my-table-name>
- 已从 ADLS Gen2 存储帐户容器中删除 _checkpoint 文件夹。
完成上述步骤后,重新运行 json 特定架构并得到应用。
在 Databricks 中,table 是使用架构 json 定义创建的。
架构 json 用于创建 table
{
"fields": [
{
"metadata": {},
"name": "username",
"nullable": true,
"type": "string"
},
{
"metadata": {},
"name": "department",
"nullable": true,
"type": "string"
},
{
"metadata": {},
"name": "income",
"nullable": true,
"type": "decimal(38,18)"
}
],
"type" :"struct"
}
下面的代码创建 table
...
# the schema json file is placed in a location and using it to create table
with open('/dbfs/FileStore/my-schema/{0}.json'.format(tbl_name), 'r') as f:
# data files
tbl_schema = T.StructType.fromJson(json.loads(f.read()))
tbl_df = spark.createDataFrame([], tbl_schema)
tbl_df.write.format("delta").save(tbl_path)
# create table.
spark.sql("CREATE TABLE {0} USING DELTA LOCATION '{1}'".format(tbl_name, tbl_path))
...
当我 describe
table 时,我看到收入字段的 DecimalType(10,0)。
我正在使用读取流从 ORC 文件中读取数据,其中使用 Decimal(38,18),能够在数据帧中打印 Scehma()。
我正在使用 Spark 结构化流写入流,它使用 UPSERT(合并到),使用 foreachBatch()。
类似于此 link https://docs.azuredatabricks.net/_static/notebooks/merge-in-streaming.html
中的 python 示例问题:
每当我 运行 时 table 没有插入数据。也没有调试日志消息。
我想这个问题可能是由于 table 中的字段收入是 DecimalType(10,0),而数据帧是 DecimalType(38,18)。
所以我正在尝试改变字段,但无法做到。我正在使用以下命令。
%sql ALTER TABLE mytable ALTER income TYPE decimal(38,18);
com.databricks.backend.common.rpc.DatabricksExceptions$SQLExecutionException: org.apache.spark.sql.AnalysisException: ALTER TABLE CHANGE COLUMN is not supported for changing column 'income' with type 'DecimalType(10,0) (nullable = true)' to 'income' with type 'DecimalType(38,18) (nullable = true)'
at com.databricks.sql.transaction.tahoe.DeltaErrors$.alterTableChangeColumnException(DeltaErrors.scala:478)
at com.databricks.sql.transaction.tahoe.commands.AlterTableChangeColumnDeltaCommand.verifyColumnChange(alterDeltaTableCommands.scala:412)
at com.databricks.sql.transaction.tahoe.commands.AlterTableChangeColumnDeltaCommand.$anonfun$run(alterDeltaTableCommands.scala:295)
at com.databricks.sql.transaction.tahoe.schema.SchemaUtils$.transform(SchemaUtils.scala:762)
at com.databricks.sql.transaction.tahoe.schema.SchemaUtils$.transformColumnsStructs(SchemaUtils.scala:781)
at com.databricks.sql.transaction.tahoe.commands.AlterTableChangeColumnDeltaCommand.$anonfun$run(alterDeltaTableCommands.scala:292)
at com.databricks.spark.util.FrameProfiler$.record(FrameProfiler.scala:80)
at com.databricks.sql.transaction.tahoe.metering.DeltaLogging.$anonfun$recordDeltaOperation(DeltaLogging.scala:122
如果我删除 TYPE ,我会得到下面的异常
com.databricks.backend.common.rpc.DatabricksExceptions$SQLExecutionException: org.apache.spark.sql.catalyst.parser.ParseException:
mismatched input 'decimal' expecting {<EOF>, ';'}(line 1, pos 46)
== SQL ==
ALTER TABLE ahm_db.message_raw ALTER income decimal(38,18)
----------------------------------------------^^^
at org.apache.spark.sql.catalyst.parser.ParseException.withCommand(ParseDriver.scala:265)
at org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parse(ParseDriver.scala:134)
at org.apache.spark.sql.execution.SparkSqlParser.parse(SparkSqlParser.scala:64)
at org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parsePlan(ParseDriver.scala:85)
at com.databricks.sql.parser.DatabricksSqlParser.$anonfun$parsePlan(DatabricksSqlParser.scala:67)
at com.databricks.sql.parser.DatabricksSqlParser.parse(DatabricksSqlParser.scala:87)
因为在我的例子中是 delta lake store,所以启用了 options('checkpoint','/_checkpoint')
选项。数据参考仍然可用。
在开发过程中,删除 table 并使用 vaccum 优化后。
%sql delete from <my-table-name>
spark.conf.set('spark.databricks.delta.retentionDurationCheck.enabled','false')
# use spark.conf.get('property') to check default or current value
# Per documentation setting retention duration less than 7 days is not a recommended practice, but depends on requirements
%sql
VACUUM <my-table-name> RETAIN 0 HOURS
%sql
drop table <my-table-name>
- 已从 ADLS Gen2 存储帐户容器中删除 _checkpoint 文件夹。
完成上述步骤后,重新运行 json 特定架构并得到应用。