具有列定义的 parquet 文件中的 Synapse CETAS 失败

Synapse CETAS from parquet file with columns definition is failing

提问人:Jean-Christophe 提问时间:9/5/2023 更新时间:9/7/2023 访问量:131

问:

在 Synapse 管道中,我尝试使用之前生成的 parquet 文件(从 Azure SQL 数据库)中的 CETAS 脚本活动。 源数据库包含一些包含 LOB 列(xml 类型)的表,因此默认的 varchar(8000) 类型不足以满足某些值。 我尝试定义列和类型:

CREATE EXTERNAL TABLE myTable ([column1] int, [column2] varchar(MAX))
WITH (
        LOCATION = 'myLocation',
        DATA_SOURCE = mySource,
        FILE_FORMAT = Parquet
) 
AS
SELECT * FROM OPENROWSET(BULK 'myParquetFile.parquet',
    FORMAT='PARQUET') AS f;

我的实际表有 24 列(不仅仅是上面脚本中的 2 列),但是我在运行脚本时收到以下消息:

{
    "errorCode": "2011",
    "message": "Different number of columns in CREATE TABLE or CREATE EXTERNAL TABLE and SELECT query.",
    "failureType": "UserError",
    "target": "myScriptName",
    "details": []
}

使用 parquet 文件查看器进行检查时,它确实包含 24 列,与我在 CETAS 脚本中传递的列定义完全相同。 镶木地板文件中是否存在一种“隐藏”列?我应该用 24 列的确切列表替换“SELECT *”吗?

感谢您的帮助!

azure-data-factory parquet azure-synapse external-tables

评论

0赞 Jean-Christophe 9/5/2023
“我应该用 24 列的确切列表替换”SELECT *“吗?”不起作用,我只是尝试过。同样的错误。
0赞 Rakesh Govindula 9/5/2023
你在普通脚本中尝试过同样的方法吗?这是否会导致与脚本活动相同的错误?
0赞 Jean-Christophe 9/5/2023
感谢您的回复!是的,我尝试将其作为独立脚本活动进行尝试,并得到相同的结果(但我使用的是通过上一个复制活动生成的相同 parquet 文件)

答:

1赞 Bhavani 9/5/2023 #1

当我尝试使用以下脚本复制问题时:

CREATE EXTERNAL TABLE myTable ([EMPLOYEE_ID] int, [FIRST_NAME] varchar(MAX))
WITH (
        LOCATION = '<location>',
        DATA_SOURCE = '<dataSource>',
        FILE_FORMAT = <fileFormat>
) 
AS
SELECT * FROM OPENROWSET(BULK 'employees.parquet',
    FORMAT='PARQUET') AS f;

我遇到了类似的错误:

enter image description here

我使用以下脚本来解决这个问题:

CREATE EXTERNAL TABLE dbo.emp (
    [EMPLOYEE_ID] int,
    [FIRST_NAME] varchar(MAX)
)
WITH (
    LOCATION = '<location>',
    DATA_SOURCE = <dataSource>,
    FILE_FORMAT = <fileFormat>
)

脚本活动已成功运行,未出现任何错误:

enter image description here

已创建外部表:

enter image description here

如果要从源中获取所有列,可以使用以下代码:

SELECT *
FROM OPENROWSET(
    BULK '<filePath>',
    FORMAT='PARQUET'
) AS [dbo.employee];

评论

0赞 Jean-Christophe 9/6/2023
感谢您@Bhavani花时间在这件事上!如果我理解,您只保留创建外部表的脚本部分,并删除“AS SELECT *”部分。我没有得到的是,我无法在创建表后查询该表(在您的示例中为“dbo.employees1”):“外部表'myTable'无法访问,因为位置不存在或被另一个进程使用。LOCATION 参数应该包含使用 CETAS 语句时生成的 parquet 文件,但它根本不存在,因为在创建表时未使用 SELECT * FROM OPENROWSET (...)。
0赞 Jean-Christophe 9/7/2023 #2

我最终调整了源 parquet 文件(创建外部表之前的步骤)。带有 LOB 的列包含我不一定需要的 xml 代码。我截断了它们以保持在 8000 个字符的限制范围内(并使用 CETAS 语句,而无需定义列架构) 在复制活动中,我在源的 SELECT 中使用了以下语句: LEFT(CONVERT(NVARCHAR(MAX),[myColumnToTruncate]),8000) AS [myColumnToTruncate] 这并不完美,因为数据没有完全保留,但这符合我的要求。 感谢@RakeshGovindula和@Bhavani抽出宝贵时间回答!