具有infer_schema功能的转换/元数据

transformation/metadata with infer_schema function

提问人:naomitrina 提问时间:7/21/2023 更新时间:7/24/2023 访问量:106

问:

我在 Snowflake 中创建了一个过程器,它使用 infer_schema 函数根据加载到内部阶段的文件的结构动态创建表。目前,该阶段中有六个不同的文件。这个过程正是我想要的。但是,我想知道是否有办法将文件名添加为表中的列。

这是我所拥有的:

Create or replace table t1
     using template (
         select array_agg(object_construct(*))
           from table(
              infer_schema(
                 location => 'stage'
                   file_format => 'file_format'
                     )
                      )
                           );

copy into t1
from @stage
file_format = 'file_format'
match_by_column_name = case_insensitive;

虽然这可行,但我想要一个添加了文件名的列。通常,我会这样做

copy into t1
select metadate$filename
from stage

但我不确定我如何在这里做到这一点。

sql 雪花云数据平台

评论

0赞 Mike Walton 7/21/2023
您是否考虑使用动态脚本(SP 或 Snowflake 脚本)在创建 t1 后读取 t1 的定义,然后使用表定义在 copy into 语句中指定列?从理论上讲,您可以简单地使用 alter table 语句向 t1 添加一个文件名列,然后使用指定列的选择将副本编写为脚本。

答:

0赞 Travis 7/24/2023 #1

目前没有办法在单个语句中做到这一点。但是,您可以链接后续语句以添加所需的任何其他列:create table using templatecreate table as select

create table T0
using template (
    select *
    from table(
        infer_schema(
            location => '@STAGE_NAME',
            file_format => 'FILE_FORMAT_NAME'
        )
    )
);

create table T1
as (
    select
        *,
        null::varchar as MY_COLUMN_NAME
    from T0
    limit 0
);

drop table T0;

在前面的示例中,“T1”是所需的表名,而“T0”只是任何占位符表名。

语句中的子句使该查询仅返回 T0 的列定义,而不是任何实际数据。实际上,这允许您以可扩展的方式复制 T0 的定义。也就是说,它允许您预置/追加其他列。limit 0create table as select

请注意,此技术要求您提供一个“虚拟表达式”,该表达式计算结果为每个附加列的预期类型。这是因为我们将 T1 定义为查询的推断架构,而不是类型化列列表的显式架构。幸运的是,由于实际上没有返回/插入任何行(由于 ),我们可以通过简单地转换为预期的数据类型来提供虚拟表达式。limit 0null