你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
在 Azure Database for PostgreSQL 灵活服务器中使用 azure_storage 扩展导入和导出数据
适用于: Azure Database for PostgreSQL 灵活服务器
azure_storage扩展允许直接在 Azure 存储 帐户与 Azure Database for PostgreSQL 灵活服务器的实例之间导入或导出多种文件格式的数据。
可以使用此扩展导出和导入数据的示例,请参阅 本文的“示例 ”部分。
若要在 azure_storage
Azure Database for PostgreSQL 灵活服务器实例上使用扩展,需要 允许该扩展、 加载其库和 创建扩展。
过程概述
- 确定希望扩展用户
azure_storage
与之交互的Azure 存储帐户。 - 确定要对每个Azure 存储帐户的 blob 服务发出的请求使用的授权类型。
azure_storage
扩展支持 使用共享密钥进行授权,并使用 Microsoft Entra ID 进行授权。 在这两种类型的授权中,Microsoft Entra ID 提供优于共享密钥的安全性和易用性,并且是建议的一种Microsoft。 若要满足每个情况下所需的先决条件,请按照相应部分中的说明操作:- 具有 Microsoft Entra ID 的授权,或
- 使用共享密钥进行授权。
- 包括
azure_storage
:shared_preload_libraries
- 包括
azure_storage
:azure.extensions
- 使用首选客户端(例如 psql、pgAdmin 等),连接到 Azure Database for PostgreSQL 灵活服务器实例中的任何数据库。 若要创建所有 SQL 对象(表、类型、函数、视图等),可以使用
azure_storage
扩展与Azure 存储帐户的实例进行交互,请执行以下语句:CREATE EXTENSION azure_storage;
azure_storage.account_*
使用函数,添加对要让 PostgreSQL 用户或角色使用扩展访问的Azure 存储帐户的azure_storage
引用。 这些引用包括所引用的Azure 存储帐户的名称,以及与 Azure 存储 帐户交互时要使用的身份验证类型。 根据所选的身份验证类型,可能需要提供一些其他参数,例如Azure 存储帐户访问密钥或 SAS 令牌。
重要
对于必须为其提供Azure 存储帐户访问密钥的身份验证类型,请注意,Azure 存储访问密钥类似于存储帐户的根密码。 请始终小心保护它们。 使用 Azure 密钥保管库安全地管理和轮换密钥。 azure_storage
扩展将这些密钥存储在可由角色成员读取的pg_read_all_data
表中azure_storage.accounts
。
授予 azure_storage_admin
该角色的用户可以使用以下函数与 azure_storage.accounts
表交互:
- azure_storage.account_add
- azure_storage.account_list
- azure_storage.account_remove
- azure_storage.account_user_add
- azure_storage.account_user_remove
该 azure_storage_admin
角色默认授予该 azure_pg_admin
角色。
将授权与 Microsoft Entra ID 配合使用
- 在启用系统分配的托管标识后,重启 Azure Database for PostgreSQL 灵活服务器的实例。
- 将基于角色的访问控制(RBAC)权限分配给 Azure Database for PostgreSQL 灵活服务器的实例的系统分配托管标识,以便访问 Azure 存储 帐户上的 blob 数据。
将授权与共享密钥配合使用
- Azure 存储帐户必须启用“允许存储帐户密钥访问”(也就是说,它不能将其 AllowSharedKeyAccess 属性设置为 false)。
- 若要将其传递给 azure_storage.account_add 函数,请提取Azure 存储帐户的两个访问密钥之一。
函数
azure_storage.account_add
允许将存储帐户及其关联的访问密钥添加到扩展可以访问的 azure_storage
存储帐户列表的函数。
如果以前调用此函数已添加对此存储帐户的引用,则不会添加新条目,而是更新现有条目的访问密钥。
注意
此函数不会验证引用的帐户名称是否存在,或者是否可以使用提供的访问密钥进行访问。 但是,它根据对 Azure 存储帐户施加的命名验证规则来验证存储帐户的名称是否有效。
azure_storage.account_add(account_name_p text, account_key_p text);
此函数有一个重载版本,该函数接受封装account_config
所引用Azure 存储帐户的名称的参数,以及身份验证类型、帐户类型或存储凭据等所有必需设置。
azure_storage.account_add(account_config jsonb);
权限
必须是 . 的 azure_storage_admin
一个成员。
参数
account_name_p
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
account_key_p
text
存储帐户的访问密钥之一的值。 Azure Blob 存储访问密钥类似于存储帐户的根密码。 始终要小心保护访问密钥。 使用 Azure 密钥保管库安全地管理和轮换密钥。 帐户密钥存储在只能由超级用户访问的表中。 授予 azure_storage_admin
该角色的用户可以通过函数与此表进行交互。 若要查看添加的存储帐户,请使用函数 azure_storage.account_list。
account_config
jsonb
Azure 存储帐户的名称以及身份验证类型、帐户类型或存储凭据等所有必需设置。 建议使用实用工具函数 azure_storage.account_options_managed_identity、 azure_storage.account_options_credentials 或 azure_storage.account_options 来创建必须作为此参数传递的任何有效值。
返回类型
VOID
azure_storage.account_options_managed_identity
充当实用工具函数的函数,该函数可在 azure_storage.account_add 中作为参数调用,并且当使用系统分配的托管标识与 Azure 存储 帐户交互时,可为参数生成有效值account_config
。
azure_storage.account_options_managed_identity(name text, type azure_storage.storage_type);
权限
任何用户或角色都可以调用此函数。
参数
name
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
type
azure_storage.storage_type
支持的存储类型之一的值。 仅支持的值为 blob
.
返回类型
jsonb
azure_storage.account_options_credentials
充当实用工具函数的函数,可以在 azure_storage.account_add 中作为参数调用,并且当使用Azure 存储访问密钥与Azure 存储帐户交互时,可为参数生成有效值account_config
。
azure_storage.account_options_credentials(name text, credentials text, type azure_storage.storage_type);
权限
任何用户或角色都可以调用此函数。
参数
name
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
凭据
text
存储帐户的访问密钥之一的值。 Azure Blob 存储访问密钥类似于存储帐户的根密码。 始终要小心保护访问密钥。 使用 Azure 密钥保管库安全地管理和轮换密钥。 帐户密钥存储在只能由超级用户访问的表中。 授予 azure_storage_admin
该角色的用户可以通过函数与此表进行交互。 若要查看添加的存储帐户,请使用函数 azure_storage.account_list。
type
azure_storage.storage_type
支持的存储类型之一的值。 仅支持的值为 blob
.
返回类型
jsonb
azure_storage.account_options
充当实用工具函数的函数,可在 azure_storage.account_add 中调用为参数,并且当使用Azure 存储访问密钥或系统分配的托管标识与Azure 存储帐户交互时,该函数可用于生成参数的有效值account_config
。
azure_storage.account_options(name text, auth_type azure_storage.auth_type, storage_type azure_storage.storage_type, credentials text DEFAULT NULL);
权限
任何用户或角色都可以调用此函数。
参数
name
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
auth_type
azure_storage.auth_type
支持的存储类型之一的值。 仅支持的值和 access-key
managed-identity
。
storage_type
azure_storage.storage_type
支持的存储类型之一的值。 仅支持的值为 blob
.
凭据
text
存储帐户的访问密钥之一的值。 Azure Blob 存储访问密钥类似于存储帐户的根密码。 始终要小心保护访问密钥。 使用 Azure 密钥保管库安全地管理和轮换密钥。 帐户密钥存储在只能由超级用户访问的表中。 授予 azure_storage_admin
该角色的用户可以通过函数与此表进行交互。 若要查看添加的存储帐户,请使用函数 azure_storage.account_list。
返回类型
jsonb
azure_storage.account_remove
允许从扩展可以访问的存储帐户列表中删除存储帐户及其关联的访问密钥的 azure_storage
函数。
azure_storage.account_remove(account_name_p text);
权限
必须是 . 的 azure_storage_admin
一个成员。
参数
account_name_p
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
返回类型
VOID
azure_storage.account_user_add
允许通过扩展提供的函数授予 PostgreSQL 用户或角色对存储帐户的访问权限的 azure_storage
函数。
注意
仅当存储帐户(其名称作为第一个参数传递)已使用 azure_storage.account_add 创建,并且如果用户或角色(其名称作为第二个参数传递)已存在,则此函数的执行才会成功。
azure_storage.account_add(account_name_p text, user_p regrole);
权限
必须是 . 的 azure_storage_admin
一个成员。
参数
account_name_p
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
user_p
regrole
服务器上可用的 PostgreSQL 用户或角色的名称。
返回类型
VOID
azure_storage.account_user_remove
允许通过扩展提供的函数撤消 PostgreSQL 用户或角色对存储帐户的访问权限的 azure_storage
函数。
注意
仅当名称作为第一个参数传递的存储帐户已使用 azure_storage.account_add 创建,并且名称作为第二个参数传递的用户或角色仍然存在时,此函数的执行才会成功。
从服务器中删除用户或角色时,通过执行DROP USER | ROLE
,也会自动消除对Azure 存储帐户的任何引用所授予的权限。
azure_storage.account_user_remove(account_name_p text, user_p regrole);
权限
必须是 . 的 azure_storage_admin
一个成员。
参数
account_name_p
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
user_p
regrole
服务器上可用的 PostgreSQL 用户或角色的名称。
返回类型
VOID
azure_storage.account_list
列出通过 azure_storage.account_add 函数配置的存储帐户的名称,以及授予通过扩展提供的 azure_storage
函数与该存储帐户交互的权限的 PostgreSQL 用户或角色。
azure_storage.account_list();
权限
必须是 . 的 azure_storage_admin
一个成员。
参数
此函数不采用任何参数。
返回类型
TABLE(account_name text, auth_type azure_storage.auth_type, azure_storage_type azure_storage.storage_type, allowed_users regrole[])
添加了Azure 存储帐户列表、用于与每个帐户交互的身份验证类型、存储类型以及授予其访问权限的 PostgreSQL 用户或角色列表的四列表。
azure_storage.blob_list
列出存储在引用存储帐户的给定容器中的 blob 的名称和其他属性(size、lastModified、eTag、contentType、contentEncoding 和 contentHash)。
azure_storage.blob_list(account_name text, container_name text, prefix text DEFAULT ''::text);
权限
通过执行 azure_storage.account_user_add,必须将调用此函数的用户或角色添加到所引用的允许列表中account_name
。 azure_storage_admin
系统会自动允许成员引用使用 azure_storage.account_add 添加其引用的所有Azure 存储帐户。
参数
account_name
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
container_name
text
容器的名称。 容器对一组 blob 进行组织,类似于文件系统中的目录。 一个存储帐户可以包含无限数量的容器,一个容器可以存储无限数量的 Blob。
容器名称必须是有效的域名系统(DNS)名称,因为它构成了用于对容器或其 Blob 进行寻址的唯一 URI 的一部分。
命名容器时,请确保遵循 这些规则。
容器的 URI 类似于:https://myaccount.blob.core.windows.net/mycontainer
前缀
text
指定时,该函数返回名称以此参数中提供的值开头的 blob。 默认为空字符串。
返回类型
TABLE(path text, bytes bigint, last_modified timestamp with time zone, etag text, content_type text, content_encoding text, content_hash text)
每个 Blob 返回一条记录的表,包括 blob 的全名和其他一些属性。
path
text
blob 的全名。
字节
bigint
blob 的大小(以字节为单位)。
last_modified
timestamp with time zone
上次修改 Blob 的日期和时间。 任何修改 Blob 的操作(包括 Blob 元数据或属性更新)都会更改 Blob 的上次修改时间。
etag
text
ETag 属性用于更新期间的乐观并发。 它不是时间戳,因为有另一个名为 Timestamp 的属性用于存储上次更新记录的时间。 例如,如果加载实体并想要更新它,则 ETag 必须与当前存储的内容匹配。 设置适当的 ETag 非常重要,因为如果有多个用户正在编辑同一项,你希望他们不会覆盖彼此所做的更改。
content_type
text
为 Blob 指定的内容类型。 默认内容类型为 application/octet-stream
.
content_encoding
text
blob 的 Content-Encoding 属性,Azure 存储允许你定义。 对于压缩内容,可以将属性设置为 Gzip。 浏览器访问内容时,会自动解压缩内容。
content_hash
text
用于在传输过程中验证 Blob 完整性的哈希。 指定此标头后,存储服务会检查提供的哈希,其中包含一个从内容中计算得出的哈希。 如果这两个哈希值不匹配,操作会失败,并显示错误代码 400(错误请求)。
azure_storage.blob_get
允许导入数据的函数。 它会从Azure 存储帐户中的 blob 容器下载文件。 然后,它将内容转换为行,可以使用 SQL 语言构造来使用和处理这些行。 此函数添加了对在导入 Blob 容器之前筛选和操作从 Blob 容器提取的数据的支持。
注意
在尝试访问所引用存储帐户的容器之前,此函数会根据对 Azure 存储帐户施加的命名验证规则来检查作为参数传递的存储帐户的名称和容器是否有效。 如果其中任一项无效,则会引发错误。
azure_storage.blob_get(account_name text, container_name text, path text, decoder text DEFAULT 'auto'::text, compression text DEFAULT 'auto'::text, options jsonb DEFAULT NULL::jsonb);
此函数有一个重载版本,它接受一个 rec
参数,允许你方便地定义输出格式记录。
azure_storage.blob_get(account_name text, container_name text, path text, rec anyelement, decoder text DEFAULT 'auto'::text, compression text DEFAULT 'auto'::text, options jsonb DEFAULT NULL::jsonb);
权限
通过执行 azure_storage.account_user_add,必须将调用此函数的用户或角色添加到所引用的允许列表中account_name
。 azure_storage_admin
系统会自动允许成员引用使用 azure_storage.account_add 添加其引用的所有Azure 存储帐户。
参数
account_name
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
container_name
text
容器的名称。 容器对一组 blob 进行组织,类似于文件系统中的目录。 一个存储帐户可以包含无限数量的容器,一个容器可以存储无限数量的 Blob。
容器名称必须是有效的域名系统(DNS)名称,因为它构成了用于对容器或其 Blob 进行寻址的唯一 URI 的一部分。
命名容器时,请确保遵循 这些规则。
容器的 URI 类似于:https://myaccount.blob.core.windows.net/mycontainer
path
text
blob 的全名。
rec
anyelement
记录输出结构的定义。
解码器
text
blob 格式的规范。 可以设置为以下任何值:
Format | 默认值 | 描述 |
---|---|---|
auto |
true |
根据分配给 Blob 名称的最后一系列字符推断值。 如果 blob 名称以.csv 或结尾,则假定csv 为 < a0/.csv.gz >。 如果以 .tsv 或结尾 .tsv.gz ,则假定 tsv 为 。 如果以 .json 、、.json.gz 、.xml .xml.gz 、 .txt 或.txt.gz 结尾,则假定text 它。 |
csv |
PostgreSQL COPY 使用的逗号分隔值格式。 | |
tsv |
制表符分隔的值,默认 PostgreSQL COPY 格式。 | |
binary |
二进制 PostgreSQL COPY 格式。 | |
text | xml | json |
包含单个文本值的文件。 |
compression
text
压缩类型的规范。 可以设置为以下任何值:
Format | 默认值 | 描述 |
---|---|---|
auto |
true |
根据分配给 Blob 名称的最后一系列字符推断值。 如果 blob 名称以结尾 .gz ,则假定 gzip 为 < a0/>。 否则,它假定 none 为 . |
gzip |
强制使用 gzip 解码器解压缩 blob。 | |
none |
强制将 Blob 视为不需要解压缩的 Blob。 |
该扩展不支持任何其他压缩类型。
选项
jsonb
定义处理自定义标头、自定义分隔符、转义字符等的设置。 options
影响此函数的行为的方式类似于在 PostgreSQL 中传递给 COPY
命令的选项如何影响其行为。
返回类型
SETOF record
SETOF anyelement
azure_storage.blob_put
通过将文件上传到Azure 存储帐户中的 blob 容器,允许导出数据的函数。 文件的内容是从 PostgreSQL 中的行生成的。
注意
在尝试访问所引用存储帐户的容器之前,此函数会根据对 Azure 存储帐户施加的命名验证规则来检查作为参数传递的存储帐户的名称和容器是否有效。 如果其中任一项无效,则会引发错误。
azure_storage.blob_put(account_name text, container_name text, path text, tuple record)
RETURNS VOID;
有一个重载的函数版本,它包含 encoder
参数,可用于指定编码器在无法从参数扩展 path
推断时使用,或者想要重写推断的编码器时使用。
azure_storage.blob_put(account_name text, container_name text, path text, tuple record, encoder text)
RETURNS VOID;
函数的重载版本还包含一个 compression
参数,可用于指定在无法从参数扩展 path
推断压缩时要使用的压缩,或者想要重写推断的压缩。
azure_storage.blob_put(account_name text, container_name text, path text, tuple record, encoder text, compression text)
RETURNS VOID;
函数的重载版本还包含用于 options
处理自定义标头、自定义分隔符、转义字符等的参数, options
其工作方式与可在 PostgreSQL 中传递给 COPY
命令的选项类似。
azure_storage.blob_put(account_name text, container_name text, path text, tuple record, encoder text, compression text, options jsonb)
RETURNS VOID;
权限
通过执行 azure_storage.account_user_add,必须将调用此函数的用户或角色添加到所引用的允许列表中account_name
。 azure_storage_admin
系统会自动允许成员引用使用 azure_storage.account_add 添加其引用的所有Azure 存储帐户。
参数
account_name
text
包含所有对象的 Azure Blob 存储帐户的名称:Blob、文件、队列和表。 存储帐户提供可通过 HTTPS 从世界上任何地方访问的唯一命名空间。
container_name
text
容器的名称。 容器对一组 blob 进行组织,类似于文件系统中的目录。 一个存储帐户可以包含无限数量的容器,一个容器可以存储无限数量的 Blob。
容器名称必须是有效的域名系统(DNS)名称,因为它构成了用于对容器或其 Blob 进行寻址的唯一 URI 的一部分。
命名容器时,请确保遵循 这些规则。
容器的 URI 类似于:https://myaccount.blob.core.windows.net/mycontainer
path
text
blob 的全名。
tuple
record
记录输出结构的定义。
编码器
text
blob 格式的规范。 可以设置为以下任何值:
Format | 默认值 | 描述 |
---|---|---|
auto |
true |
根据分配给 Blob 名称的最后一系列字符推断值。 如果 blob 名称以.csv 或结尾,则假定csv 为 < a0/.csv.gz >。 如果以 .tsv 或结尾 .tsv.gz ,则假定 tsv 为 。 如果以 .json 、、.json.gz 、.xml .xml.gz 、 .txt 或.txt.gz 结尾,则假定text 它。 |
csv |
PostgreSQL COPY 使用的逗号分隔值格式。 | |
tsv |
制表符分隔的值,默认 PostgreSQL COPY 格式。 | |
binary |
二进制 PostgreSQL COPY 格式。 | |
text | xml | json |
包含单个文本值的文件。 |
compression
text
压缩类型的规范。 可以设置为以下任何值:
Format | 默认值 | 描述 |
---|---|---|
auto |
true |
根据分配给 Blob 名称的最后一系列字符推断值。 如果 blob 名称以结尾 .gz ,则假定 gzip 为 < a0/>。 否则,它假定 none 为 . |
gzip |
强制使用 gzip 解码器解压缩 blob。 | |
none |
强制将 Blob 视为不需要解压缩的 Blob。 |
该扩展不支持任何其他压缩类型。
选项
jsonb
定义处理自定义标头、自定义分隔符、转义字符等的设置。 options
影响此函数的行为的方式类似于在 PostgreSQL 中传递给 COPY
命令的选项如何影响其行为。
返回类型
VOID
azure_storage.options_csv_get
充当实用工具函数的函数(可在其中 blob_get
调用为参数),可用于解码 csv 文件的内容。
azure_storage.options_csv_get(delimiter text DEFAULT NULL::text, null_string text DEFAULT NULL::text, header boolean DEFAULT NULL::boolean, quote text DEFAULT NULL::text, escape text DEFAULT NULL::text, force_not_null text[] DEFAULT NULL::text[], force_null text[] DEFAULT NULL::text[], content_encoding text DEFAULT NULL::text);
权限
任何用户或角色都可以调用此函数。
参数
delimiter
text
分隔文件每行(行)中的列的字符。 它必须是单个 1 字节字符。 尽管此函数支持任意数量的字符的分隔符,但如果尝试使用多个 1 字节字符,PostgreSQL 会报告错误 COPY delimiter must be a single one-byte character
。
null_string
text
表示 null 值的字符串。 默认值为文本格式的 \N (反斜杠-N),CSV 格式为未加引号的空字符串。 对于不希望将 null 与空字符串区分开来的情况,即使文本格式也首选空字符串。
标头的值开始缓存响应
boolean
指示文件是否包含标题行以及文件中每列的名称的标志。 输出时,初始行包含表中的列名。
引号
text
引用数据值时要使用的引号字符。 默认为双引号。 它必须是单个 1 字节字符。 尽管此函数支持任意数量的字符的分隔符,但如果尝试使用多个 1 字节字符,PostgreSQL 会报告错误 COPY quote must be a single one-byte character
。
escape
text
应出现在与 QUOTE 值匹配的数据字符之前显示的字符。 默认值与“引号”值相同 (因此,如果引号字符出现在数据中,则将使用双引号)。 它必须是单个 1 字节字符。 尽管此函数支持任意数量的字符的分隔符,但如果尝试使用多个 1 字节字符,PostgreSQL 会报告错误 COPY escape must be a single one-byte character
。
force_not_null
text[]
与 null 字符串不匹配指定的列值。 在 null 字符串为空的默认情况下,这意味着空值将读取为零长度字符串而不是 null,即使它们未用引号括起来。
force_null
text[]
将指定的列的值与 null 字符串匹配,即使带引号,如果找到匹配项,则将该值设置为 NULL。 在 null 字符串为空的默认情况下,它会将带引号的空字符串转换为 NULL。
content_encoding
text
对文件进行编码的编码的名称。 如果省略该选项,则使用当前客户端编码。
返回类型
jsonb
azure_storage.options_copy
充当实用工具函数的函数,可在其中 blob_get
调用为参数。 它充当options_csv_get、options_tsv和options_binary的帮助程序函数。
azure_storage.options_copy(delimiter text DEFAULT NULL::text, null_string text DEFAULT NULL::text, header boolean DEFAULT NULL::boolean, quote text DEFAULT NULL::text, escape text DEFAULT NULL::text, force_quote text[] DEFAULT NULL::text[], force_not_null text[] DEFAULT NULL::text[], force_null text[] DEFAULT NULL::text[], content_encoding text DEFAULT NULL::text);
权限
任何用户或角色都可以调用此函数。
参数
delimiter
text
分隔文件每行(行)中的列的字符。 它必须是单个 1 字节字符。 尽管此函数支持任意数量的字符的分隔符,但如果尝试使用多个 1 字节字符,PostgreSQL 会报告错误 COPY delimiter must be a single one-byte character
。
null_string
text
表示 null 值的字符串。 默认值为文本格式的 \N (反斜杠-N),CSV 格式为未加引号的空字符串。 对于不希望将 null 与空字符串区分开来的情况,即使文本格式也首选空字符串。
标头的值开始缓存响应
boolean
指示文件是否包含标题行以及文件中每列的名称的标志。 输出时,初始行包含表中的列名。
引号
text
引用数据值时要使用的引号字符。 默认为双引号。 它必须是单个 1 字节字符。 尽管此函数支持任意数量的字符的分隔符,但如果尝试使用多个 1 字节字符,PostgreSQL 会报告错误 COPY quote must be a single one-byte character
。
escape
text
应出现在与 QUOTE 值匹配的数据字符之前显示的字符。 默认值与“引号”值相同 (因此,如果引号字符出现在数据中,则将使用双引号)。 它必须是单个 1 字节字符。 尽管此函数支持任意数量的字符的分隔符,但如果尝试使用多个 1 字节字符,PostgreSQL 会报告错误 COPY escape must be a single one-byte character
。
force_quote
text[]
强制引用用于每个指定列中所有非 NULL 值。 始终不对 NULL 输出使用引号。 如果指定了 *,则所有列中的非 NULL 值都使用引号。
force_not_null
text[]
与 null 字符串不匹配指定的列值。 在 null 字符串为空的默认情况下,这意味着空值将读取为零长度字符串而不是 null,即使它们未用引号括起来。
force_null
text[]
将指定的列的值与 null 字符串匹配,即使带引号,如果找到匹配项,则将该值设置为 NULL。 在 null 字符串为空的默认情况下,它会将带引号的空字符串转换为 NULL。
content_encoding
text
对文件进行编码的编码的名称。 如果省略该选项,则使用当前客户端编码。
返回类型
jsonb
azure_storage.options_tsv
充当实用工具函数的函数(可在其中 blob_get
调用为参数),可用于解码 tsv 文件的内容。
azure_storage.options_tsv(delimiter text DEFAULT NULL::text, null_string text DEFAULT NULL::text, content_encoding text DEFAULT NULL::text);
权限
任何用户或角色都可以调用此函数。
参数
delimiter
text
分隔文件每行(行)中的列的字符。 它必须是单个 1 字节字符。 尽管此函数支持任意数量的字符的分隔符,但如果尝试使用多个 1 字节字符,PostgreSQL 会报告错误 COPY delimiter must be a single one-byte character
。
null_string
text
表示 null 值的字符串。 默认值为文本格式的 \N (反斜杠-N),CSV 格式为未加引号的空字符串。 对于不希望将 null 与空字符串区分开来的情况,即使文本格式也首选空字符串。
content_encoding
text
对文件进行编码的编码的名称。 如果省略该选项,则使用当前客户端编码。
返回类型
jsonb
azure_storage.options_binary
充当实用工具函数的函数(可在其中 blob_get
调用为参数),可用于解码二进制文件的内容。
azure_storage.options_binary(content_encoding text DEFAULT NULL::text);
权限
任何用户或角色都可以调用此函数。
参数
content_encoding
text
对文件进行编码的编码的名称。 如果省略该选项,则使用当前客户端编码。
返回类型
jsonb
可能的错误
错误:azure_storage:权限不足以执行请求的操作
在执行与Azure 存储(azure_storage.blob_list
或azure_storage.blob_put
)交互的任何函数时,azure_storage.blob_get
系统分配的托管标识未授予足够的数据平面角色或权限(通常为 azure_storage.blob_put 的存储 Blob 数据参与者和另外两个函数的最小存储 Blob 数据读取器)。
也可能是你已经授予了最低所需权限,但它们尚未生效。 传播这些权限可能需要几分钟时间。
错误:azure_storage:缺少存储凭据
执行与Azure 存储(azure_storage.blob_list
azure_storage.blob_get
或azure_storage.blob_put
)交互的任何函数以及希望扩展使用存储帐户进行身份验证的凭据时,不会使用 azure_storage.account_add
< a0/> 注册。
错误:azure_storage:连接时出现内部错误
灵活服务器的实例无法访问目标存储帐户时。 这种情况可能发生在以下情况下:
- 存储帐户不存在。
- 网络配置不允许来自灵活服务器的实例的流量访问存储帐户。 例如,当使用公共访问网络部署灵活服务器的实例时,只能通过专用终结点访问存储帐户。
在灵活服务器实例中未启用系统分配的托管标识时。
错误:azure_storage:存储凭据格式无效
在灵活服务器的实例上启用系统分配的托管标识时,但启用后服务器尚未重启。
错误:azure_storage:不允许当前用户 <user_or_role> 使用存储帐户 <account_name>
执行与Azure 存储(azure_storage.blob_list
或)交互的任何函数(或azure_storage.blob_put
)与用户或角色交互时,azure_storage.blob_get
该用户或角色不是其成员azure_storage_admin
且未授予权限(使用azure_storage.account_user_add
)使用引用的存储帐户。
示例
必须先满足以下先决条件,然后才能运行以下示例:
- 创建 Azure 存储帐户。
若要创建Azure 存储帐户,如果还没有帐户,请自定义值
<resource_group>
、<location>
、<account_name>
以及<container_name>
运行以下 Azure CLI 命令:resource_group=<resource_group> location=<location> storage_account=<account_name> blob_container=<container_name> az group create --name $resource_group --location $location az storage account create --resource-group $resource_group --name $storage_account --location $location --sku Standard_LRS --kind BlobStorage --public-network-access enabled --access-tier hot
- 创建 Blob 容器。
若要创建 Blob 容器,请运行以下 Azure CLI:
az storage container create --account-name $storage_account --name $blob_container -o tsv
- 提取分配给存储帐户的两个访问密钥之一。 请确保复制access_key的值,因为需要在后续步骤中将其作为参数 传递给 azure_storage.account_add 。
若要提取两个访问密钥中的第一个,请运行以下 Azure CLI 命令:
access_key=$(az storage account keys list --resource-group $resource_group --account-name $storage_account --query [0].value) echo "Following is the value of your access key:" echo $access_key
- 下载包含示例期间使用的数据集的文件,并将其上传到 Blob 容器。
若要使用数据集下载文件,请运行以下 Azure CLI 命令:
mkdir --parents azure_storage_examples cd azure_storage_examples curl -O https://examples.citusdata.com/tutorial/events.csv gzip -k events.csv cp events.csv events_blob_without_extension cp events.csv events_pipe.csv cp events.csv.gz events_compressed sed -i 's/,/|/g' events_pipe.csv az storage blob upload-batch --account-name $storage_account --destination $blob_container --source . --pattern "events*" --account-key $access_key --overwrite --output none --only-show-errors
注意
可以列出特定存储帐户中存储的容器或 blob,但前提是 PostgreSQL 用户或角色通过使用 azure_storage.account_user_add 授予对该存储帐户的引用的权限。 角色azure_storage_admin
的成员针对已使用 azure_storage.account_add 添加的所有Azure 存储帐户授予此权限。 默认情况下,仅向角色授予成员azure_pg_admin
azure_storage_admin
。
创建在其中加载数据的表
让我们创建一个表,将我们上传到存储帐户的 CSV 文件的内容导入其中。 为此,请使用首选项或客户端连接到 Azure Database for PostgreSQL 灵活服务器的PgAdmin
psql
实例,并执行以下语句:
CREATE TABLE IF NOT EXISTS events
(
event_id bigint
,event_type text
,event_public boolean
,repo_id bigint
,payload jsonb
,repo jsonb
,user_id bigint
,org jsonb
,created_at timestamp without time zone
);
添加存储帐户的访问密钥
此示例演示如何添加对存储帐户的引用,以及该存储帐户的访问密钥,该存储帐户需要通过 Azure Database for PostgreSQL 灵活服务器实例中扩展提供 azure_storage
的功能访问其内容。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
同样, <access_key>
必须设置为从存储帐户中提取的值。
SELECT azure_storage.account_add('<account_name>', '<access_key>');
提示
如果要从Azure 门户检索存储帐户名称和其中一个访问密钥,请在资源菜单中选择“访问密钥”,复制存储帐户名称,然后从 key1 部分复制密钥(必须首先选择“显示”)。
删除对存储帐户的引用
此示例演示如何删除对存储帐户的任何引用,以便当前数据库中的任何用户都无法使用 azure_storage
扩展功能访问该存储帐户。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
SELECT azure_storage.account_remove('<account_name>');
授予对 Azure Blob 存储参考上的用户或角色的访问权限
此示例演示如何授予对命名 <regular_user>
用户或角色的访问权限,以便此类 PostgreSQL 用户可以使用 azure_storage
扩展来访问托管在引用的 Azure 存储帐户托管的容器中的 Blob。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<regular_user>
必须设置为现有用户或角色的名称。
SELECT * FROM azure_storage.account_user_add('<account_name>', '<regular_user>');
列出对 Azure 存储帐户的所有引用
此示例说明如何找出扩展可在此数据库中引用哪些 Azure 存储帐户azure_storage
,以及用于访问每个存储帐户的身份验证类型,以及通过 azure_storage.account_user_add 函数授予哪些用户或角色的权限,以通过扩展提供的功能访问该 Azure 存储帐户。
SELECT * FROM azure_storage.account_list();
从 Azure Blob 存储引用上的用户或角色撤消访问权限
此示例演示如何从命名 <regular_user>
的用户或角色撤消访问权限,以便此类 PostgreSQL 用户无法使用 azure_storage
扩展访问托管在引用的 Azure 存储帐户托管的容器中的 Blob。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<regular_user>
必须设置为现有用户或角色的名称。
SELECT * FROM azure_storage.account_user_remove('<account_name>', '<regular_user>');
列出容器中的所有 Blob
此示例演示如何列出存储帐户<account_name>
容器<container_name>
中的所有现有 Blob。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
SELECT * FROM azure_storage.blob_list('<account_name>','<container_name>');
列出具有特定 Blob 名称前缀的对象
此示例演示如何列出存储帐户<account_name>
容器<container_name>
内的所有现有 blob,其 blob 名称以<blob_name_prefix>
其开头。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
<blob_name_prefix>
应设置为要枚举 Blob 的任何前缀,以包含在其名称中。 如果要返回所有 Blob,可以将此参数设置为空字符串,甚至不指定此参数的值,在这种情况下,该值默认为空字符串。
SELECT * FROM azure_storage.blob_list('<account_name>','<container_name>','<blob_name_prefix>');
或者,可以使用以下语法:
SELECT * FROM azure_storage.blob_list('<account_name>','<container_name>') WHERE path LIKE '<blob_name_prefix>%';
从容器中的 Blob 读取内容
该blob_get
函数在存储的引用容器<container_name>
<account_name>
中检索一个特定 Blob(events.csv
在本例中)的内容。 为了 blob_get
了解如何分析可在窗体 NULL::table_name
中传递值的数据,其中 table_name
引用的表的架构与所读取的 Blob 的架构匹配。 在此示例中,它指的是 events
我们在开始时创建的表。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
<blob_name>
应设置为要读取其内容的 Blob 的完整路径。
SELECT * FROM azure_storage.blob_get
('<account_name>'
,'<container_name>'
,'events.csv'
, NULL::events)
LIMIT 5;
或者,可以使用blob_get函数之后的子句显式定义结果AS
的架构。
SELECT * FROM azure_storage.blob_get('<account_name>','<container_name>','events.csv.gz')
AS res (
event_id BIGINT
,event_type TEXT
,event_public BOOLEAN
,repo_id BIGINT
,payload JSONB
,repo JSONB
,user_id BIGINT
,org JSONB
,created_at TIMESTAMP WITHOUT TIME ZONE)
LIMIT 5;
使用解码器选项
此示例演示了选项 decoder
的使用。 通常,格式是从文件的扩展名推断出来的,但是当文件内容没有匹配的扩展名时,可以传递解码器参数。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
SELECT * FROM azure_storage.blob_get
('<account_name>'
,'<container_name>'
,'events_blob_without_extension'
, NULL::events
, decoder := 'csv')
LIMIT 5;
将压缩与解码器选项配合使用
此示例演示如何对名称不以.gz扩展名结尾的 gzip 压缩 blob 强制使用 gzip 压缩。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
SELECT * FROM azure_storage.blob_get
('<account_name>'
,'<container_name>'
,'events_compressed'
, NULL::events
, decoder := 'csv'
, compression := 'gzip')
LIMIT 5;
从 csv 格式对象加载之前导入筛选的内容和修改
此示例演示了在将 Blob 导入的内容加载到 SQL 表中之前,可以筛选和修改导入的内容。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
SELECT concat('P-',event_id::text) FROM azure_storage.blob_get
('<account_name>'
,'<container_name>'
,'events.csv'
, NULL::events)
WHERE event_type='PushEvent'
LIMIT 5;
使用标头、自定义分隔符、转义字符的文件中的查询内容
此示例演示如何通过将options_copyoptions
的结果传递给参数来使用自定义分隔符和转义字符。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
SELECT * FROM azure_storage.blob_get
('<account_name>'
,'<container_name>'
,'events_pipe.csv'
,NULL::events
,options := azure_storage.options_csv_get(delimiter := '|' , header := 'true')
);
对 Blob 内容的聚合查询
此示例演示如何对存储在 Blob 容器中的信息执行聚合操作,而无需将 Blob 的内容导入 PostgreSQL 表。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
SELECT event_type, COUNT(*) FROM azure_storage.blob_get
('<account_name>'
,'<container_name>'
,'events.csv'
, NULL::events)
GROUP BY event_type
ORDER BY 2 DESC
LIMIT 5;
使用 COPY 语句导入数据
以下示例演示如何通过COPY
命令从位于 Azure 存储 帐户<account_name>
中的 blob 容器<container_name>
中的 blob events.csv
导入数据:
创建与源文件架构匹配的表:
CREATE TABLE IF NOT EXISTS events ( event_id bigint ,event_type text ,event_public boolean ,repo_id bigint ,payload jsonb ,repo jsonb ,user_id bigint ,org jsonb ,created_at timestamp without time zone );
使用
COPY
语句将数据复制到目标表中。 指定第一行包含列标题。COPY events FROM 'https://<account_name>.blob.core.windows.net/<container_name>/events.csv' WITH (FORMAT 'csv', header);
将内容写入容器中的 Blob
该blob_put
函数构成一个特定 Blob 的内容(eventscopy.csv
在本例中),并将其上传到存储的<account_name>
引用容器<container_name>
。 此示例用于 blob_get
构造一组五行,然后传递给 blob_put
聚合函数,该函数将其作为名为 eventscopy.csv
blob 上传。
<account_name>
必须设置为存储帐户的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为storage_account环境变量的任何值匹配。
<container_name>
必须设置为 Blob 容器的名称。 如果使用了前面的脚本,此值应与在这些脚本中设置为blob_container环境变量的任何值匹配。
SELECT azure_storage.blob_put
('<account_name>'
,'<container_name>'
,'eventscopy.csv'
, top_5_events)
FROM (SELECT * FROM azure_storage.blob_get
('<account_name>'
,'<container_name>'
,'events.csv'
, NULL::events) LIMIT 5) AS top_5_events;
使用 COPY 语句导出数据
以下示例演示如何通过命令将数据从调用events
的表导出到位于 Azure 存储 帐户<account_name>
中的 blob 容器<container_name>
中的 blobevents_exported.csv
:COPY
创建与源文件架构匹配的表:
CREATE TABLE IF NOT EXISTS events ( event_id bigint ,event_type text ,event_public boolean ,repo_id bigint ,payload jsonb ,repo jsonb ,user_id bigint ,org jsonb ,created_at timestamp without time zone );
将数据加载到表中。 运行 INSERT 语句以使用多个合成行填充它,或使用 COPY 语句示例使用 Import 数据填充示例,以填充示例数据集的内容。
使用
COPY
语句将数据复制到目标表中。 指定第一行包含列标题。COPY events TO 'https://<account_name>.blob.core.windows.net/<container_name>/events_exported.csv' WITH (FORMAT 'csv', header);