#azure #azure-synapse #azure-data-lake-gen2
Вопрос:
Я использую Azure Synapse для запроса большого количества CSV-файлов с OPENROWSET
помощью команды см. Здесь. Файлы расположены в озере данных поколения 2, подключенном к Azure Synapse через управляемую идентификацию.
Это работает нормально, когда я запрашиваю только несколько файлов одновременно, однако, когда я увеличиваю количество файлов, которые я пытаюсь запросить одновременно, я получаю следующую ошибку:
Azure Synapse: Cannot bulk load because the file <file> could not be opened. Operating system error code 12(The access code is invalid.)
Вот <file>
другой файл каждый раз, когда я выполняю запрос. Если я перейду к файлу в представлении связанных данных, я смогу загрузить и просмотреть файл. Также, если я укажу, чтобы выполнить запрос к файлу, упомянутому ранее в ошибке, он будет работать нормально.
Код, который я использую для запроса к озеру данных, приведен ниже:
SELECT
Parsed.*
FROM OPENROWSET
(
bulk '2021/*/**.log',
maxerrors = 2147483647,
data_source = 'analytics',
format = 'csv',
fieldterminator ='0x0b',
fieldquote = '0x0b'
) WITH (doc nvarchar(max)) AS Rows
CROSS APPLY OPENJSON(Rows.doc)
WITH
(
col1 NVARCHAR(100),
col2 NVARCHAR(100),
...,
coln NVARCHAR(MAX)
) AS Parsed
Здесь источником данных является analytics
источник данных, указанный следующим образом:
CREATE EXTERNAL DATA SOURCE analytics
WITH
(
location = 'https://<url>.dfs.core.windows.net/analytics'
)
Я попытался указать большое число для MAXERRORS
параметра для BULK
in OPENROWSET
, так как я не возражаю, если при выполнении этого запроса будет пропущено только несколько файлов, однако это, похоже, работает только на уровне строк для ошибок, и эти ошибки находятся на уровне файлов.
Запрос выполняется здесь во встроенном бессерверном пуле.
Любые идеи о том, как обойти эту проблему, будут оценены по достоинству.
Ответ №1:
Ваш код выполняет сквозную аутентификацию в хранилище для любого пользователя AAD, подключенного к Synapse без сервера (что приведет к сбою, если вы используете логин SQL). Чтобы использовать MSI для подключения к хранилищу, вам потребуются учетные данные с областью действия базы данных, и вам нужно будет ссылаться на них во внешнем источнике данных, как в этом примере.
-- Optional: Create MASTER KEY if not exists in database:
-- CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Very Strong Password>
CREATE DATABASE SCOPED CREDENTIAL SynapseIdentity
WITH IDENTITY = 'Managed Identity';
GO
CREATE EXTERNAL DATA SOURCE mysample
WITH ( LOCATION = 'https://<storage_account>.dfs.core.windows.net/<container>/<path>',
CREDENTIAL = SynapseIdentity
)
Также ознакомьтесь с разделами этой статьи о брандмауэре в вашей учетной записи хранилища, если она заблокирована.
Ответ №2:
Просто добавляю быстрый ответ на этот вопрос. После внесения изменений, которые предложил Грег, я смог запросить немного больше данных, но все равно получил код ошибки 12.
Я поговорил со службой поддержки Azure, и они сообщили мне, что сообщение об ошибке на самом деле было 412 (но мне оно было недоступно); таким образом, это подразумевало, что файл используется/изменяется. Добавление следующего позволило синапсу Azure игнорировать это и запрашивать файл независимо от того,:
ROWSET_OPTIONS = '{"READ_OPTIONS":["ALLOW_INCONSISTENT_READS"]}'
или для внешних таблиц:
TABLE_OPTIONS = N'{"READ_OPTIONS":["ALLOW_INCONSISTENT_READS"]}'
Это сделало мой последний вопрос:
SELECT
Parsed.*
FROM OPENROWSET
(
bulk '2021/*/**.log',
maxerrors = 2147483647,
data_source = 'analytics_master_key',
format = 'csv',
fieldterminator ='0x0b',
fieldquote = '0x0b',
ROWSET_OPTIONS = '{"READ_OPTIONS":["ALLOW_INCONSISTENT_READS"]}'
) WITH (doc nvarchar(max)) AS Rows
CROSS APPLY OPENJSON(Rows.doc)
WITH
(
col1 NVARCHAR(100),
col2 NVARCHAR(100),
...,
coln NVARCHAR(MAX)
) AS Parsed