提问人:Jean-Christophe 提问时间:8/25/2023 最后编辑:AswinJean-Christophe 更新时间:8/26/2023 访问量:414
Azure Synapse >无服务器 SQL > UPSERT parquet 文件可以吗?
Azure Synapse > Serverless SQL > UPSERT parquet files is possible?
问:
我正在使用 Azure Synapse 无服务器 SQL 数据库。
我有一个使用 Azure SQL 表作为源和 Azure 存储 gen2 的第一个复制活动,其中我将 .parquet 文件存储为接收器。 从这些 .parquet 文件中,我使用 CETAS 在我的无服务器 SQL DB 中创建外部表(对于上下文:我正在使用多个 Azure SQL 数据库,因此这些外部表将允许我编写跨数据库查询)。换句话说,这个无服务器 SQL 数据库是我的 ODS 数据库。
然后,我有第二个复制活动,用于识别源表中的增量更改(使用源数据库的相应 CHANGETABLE 的SYS_CHANGE_VERSION)。第二个复制活动还会输出 .parquet 文件。
最后,我有 2 个 parquet 文件:1 个包含源表的完整内容 + 1 个包含要插入或更新的内容。无服务器 SQL 数据库中的外部表只是元数据,因此无法对它们执行 DML 操作,所以我的问题是:有没有办法将我的 2 个镶木地板文件“合并”为 1 个文件(当然没有重复),我可以用它来重新创建更新的外部表?
或者,我看到我可以在复制活动接收器中选择复制方法“Upsert”并提供 KeyColumn(我的表的 PK),但它不起作用,说:“Message=INSERT 操作不允许用于这种类型的表。(这看起来很正常,因为关联的接收器数据集指向我的外部表,这是只读的)
复制活动:
关于如何解决这个问题的任何想法? 谢谢!
答:
由于 Azure Synapse 无服务器 SQL 数据库中的外部表是只读的,因此不能使用 copy 方法直接更新外部表。Upsert
- 如果完全加载文件和增量文件位于 ADLS 中的同一文件夹中,则在创建外部表时,可以提供 filename 代替。
**
示例外部表脚本:
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>
)
此脚本将确保合并该文件夹下的所有数据。
- 当初始版本中加载的旧数据被新数据替换时,只需获取最新记录。
例 File1 数据:
PK,name,ingestion_time
1,Karikala,2023-05-01
4,Kalyani,2023-05-01
7,Sindhu,2023-05-01
File2 数据:
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型 | 名字 | ingestion_time |
---|---|---|
1 | 阿迪 | 2023-06-01 |
2 | 卡利亚尼 | 2023-05-01 |
3 | 信德 | 2023-05-01 |
此查询返回 中每个值具有最高值的行。ingestion_time
PK
external_table
评论