Azure Synapse > 无服务器 SQL > UPSERT parquet 文件是否可行?

问题描述 投票:0回答:1

我正在使用 Azure Synapse 无服务器 SQL 数据库。

我有一个使用 Azure SQL 表作为源和 Azure 存储 gen2 的第一个复制活动,我将 .parquet 文件存储在其中作为接收器。 从这些 .parquet 文件中,我使用 CETAS 在无服务器 SQL 数据库中创建外部表(对于上下文:我正在使用多个 Azure SQL 数据库,因此这些外部表将允许我编写跨数据库查询)。换句话说,这个 Serverless SQL DB 就是我的 ODS 数据库。

然后,我有第二个复制活动,用于标识源表中的增量更改(使用源数据库相应 CHANGETABLE 的 SYS_CHANGE_VERSION)。第二次复制活动还输出 .parquet 文件。

最后,我有 2 个 parquet 文件:1 个包含源表的完整内容 + 1 个包含要插入或更新的内容。无服务器 SQL 数据库中的外部表只是元数据,因此无法对它们执行 DML 操作,所以我的问题是:有没有一种方法可以将我的 2 个镶木地板文件“合并”为 1 个单个文件(当然没有重复项)我可以用来重新创建更新的外部表吗?

或者,我看到我可以在复制活动接收器中选择复制方法“Upsert”并提供 KeyColumn(我的表的 PK),但它不起作用,说:“不允许 Message=INSERT 操作这种类型的桌子。” (这看起来很正常,因为关联的接收器数据集指向我的外部表,该表是只读的)

复制活动: copy activity

知道如何解决这个问题吗? 谢谢!

serverless azure-synapse external-tables incremental
1个回答
0
投票

由于 Azure Synapse Serverless SQL 数据库中的外部表是只读的,因此无法使用

Upsert
复制方法直接更新外部表。

  • 如果完整加载文件和增量文件位于 ADLS 中的同一文件夹中,则在创建外部表时,您可以用
    **
    代替文件名。

外部表脚本示例:

CREATE  EXTERNAL  TABLE [dbo].[external_table] (
[PK] nvarchar(4000),
[name] nvarchar(4000),
[ingestion_time] nvarchar(4000)
)
WITH (
LOCATION = '<folder-name>/**',
DATA_SOURCE = <datasource-name>,
FILE_FORMAT = <fileformatname>
)

此脚本将确保合并该文件夹下的所有数据。

  • 当初始版本加载的旧数据被新数据替换时,只需取最新的记录。

例如, 文件1数据:

PK,name,ingestion_time
1,Karikala,2023-05-01
4,Kalyani,2023-05-01
7,Sindhu,2023-05-01

文件2数据:

PK,name,ingestion_time
1,Aadhi,2023-06-01

这里,File2 数据有 PK=1 的更新记录。当执行查询

select * from external_table
时,将显示所有四条记录。因此,在此外部表之上创建一个视图,以仅显示每个主键的最新记录。

示例查询:

with cte as(
SELECT *,RANK() over (partition  by PK order  by [ingestion_time] desc) as  Rank  FROM [dbo].[external_table])
select PK,name,[ingestion_time] from cte where  rank=1
PK 名字 摄取时间
1 阿迪 2023-06-01
2 卡利亚尼 2023-05-01
3 辛杜 2023-05-01

此查询返回

ingestion_time
中每个
PK
值具有最高
external_table
值的行。

© www.soinside.com 2019 - 2024. All rights reserved.