Pyspark Azure Databricks到Azure SQL DW:长文本列

Pyspark Azure Databricks到Azure SQL DW:长文本列,pyspark,azure-databricks,azure-sqldw,azure-sql-data-warehouse,azure-synapse,Pyspark,Azure Databricks,Azure Sqldw,Azure Sql Data Warehouse,Azure Synapse,我想从Azure Databricks笔记本环境中填充Azure SQL DW。我正在使用pyspark的内置连接器: sdf.write\ .format(“com.databricks.spark.sqldw”)\ .选项(“forwardSparkAzureStorageCredentials”、“true”)\ .选项(“数据库表”、“测试表”)\ .选项(“url”,url)\ .选项(“临时目录”,临时目录)\ .save() 这很好,但当我包含一个内容足够长的字符串列时,会出现一

我想从Azure Databricks笔记本环境中填充Azure SQL DW。我正在使用pyspark的内置连接器:

sdf.write\
.format(“com.databricks.spark.sqldw”)\
.选项(“forwardSparkAzureStorageCredentials”、“true”)\
.选项(“数据库表”、“测试表”)\
.选项(“url”,url)\
.选项(“临时目录”,临时目录)\
.save()
这很好,但当我包含一个内容足够长的字符串列时,会出现一个错误。我得到以下错误:

Py4JJavaError:调用o1252.save时出错。 :com.databricks.spark.sqldw.SqlDWSideException:SQL DW无法执行连接器生成的JDBC查询

基础SQLException: -com.microsoft.sqlserver.jdbc.SQLServerException:HdfsBridge::recordReaderFillBuffer-填充记录读取器缓冲区时遇到意外错误:HadoopSqlException:字符串或二进制数据将被截断。[错误代码=107090][SQLState=S0001]

据我所知,这是因为默认的字符串类型是NVARCHAR(256)。可以配置(),但NVARCHAR的最大长度为4k个字符。我的字符串偶尔达到10k字符因此,我很好奇如何将某些列导出为文本/长文本。

如果在创建表之后只执行
preActions
,我猜下面的操作会起作用。它不是,因此它失败了

sdf.write\
.format(“com.databricks.spark.sqldw”)\
.选项(“forwardSparkAzureStorageCredentials”、“true”)\
.选项(“数据库表”、“测试表”)\
.选项(“url”,url)\
.选项(“临时目录”,临时目录)\
.选项(“预操作”、“更改表测试”_tablealter COLUMN value NVARCHAR(MAX);”)\
.save()
此外,
postActions
在插入数据后执行,因此也将失败


有什么想法吗?

我有一个类似的问题,可以通过以下选项解决:

.option(“maxStrLength”,4000)

因此,在您的示例中,这将是:

sdf.write \
  .format("com.databricks.spark.sqldw") \
  .option("forwardSparkAzureStorageCredentials", "true") \
  .option("dbTable", "test_table") \
  .option("maxStrLength",4000)\
  .option("url", url) \
  .option("tempDir", temp_dir) \
  .save()
CREATE TABLE example.table
(
    NormalColumn NVARCHAR(256),
    LongColumn NVARCHAR(4000),
    VeryLongColumn NVARCHAR(MAX)
) 
WITH (HEAP)
这是:

“Spark中的StringType映射到Azure Synapse中的NVARCHAR(maxStrLength)类型。您可以使用maxStrLength为Azure Synapse中名为dbTable的表中的所有NVARCHAR(maxStrLength)类型列设置字符串长度。”

如果字符串超过4k,则应:

使用NVARCHAR(MAX)预定义表列,然后以追加模式写入表。在这种情况下,您不能使用默认的列存储索引,因此请使用堆或设置适当的索引。惰性堆是:

sdf.write \
  .format("com.databricks.spark.sqldw") \
  .option("forwardSparkAzureStorageCredentials", "true") \
  .option("dbTable", "test_table") \
  .option("maxStrLength",4000)\
  .option("url", url) \
  .option("tempDir", temp_dir) \
  .save()
CREATE TABLE example.table
(
    NormalColumn NVARCHAR(256),
    LongColumn NVARCHAR(4000),
    VeryLongColumn NVARCHAR(MAX)
) 
WITH (HEAP)
然后,您可以像往常一样对其进行写入,而无需使用maxStrLength选项。这也意味着您不会过度指定所有其他字符串列

其他选择包括:

  • 使用“拆分”将1列转换为多个字符串列
  • 另存为拼花地板,然后从synapse内部装入

  • 实际上,在大多数情况下,VARCHAR(4000)比NVARCHAR(4000)要好,但主题不同。