BIML Dataflow не может прочитать файл конфигурации - PullRequest
0 голосов
/ 30 мая 2018

Сводка

Поиск файла конфигурации работает для задачи «Выполнение SQL», но не для задач потока данных.

Проблема

У меня есть 2 базы данных:

  1. Источник (локальная база данных SQL Server)
  2. Назначение (база данных SQL Azure)

У меня есть 2 пакета, которые яхочу создать из кода BIML.

1) Создать этап (Работает нормально)

  • Создает таблицы в целевой базе данных, используя для каждого цикла и метаданные из исходной базы данных

2) Load Staging (не работает)

  • Загружает созданные таблицы в целевой базе данных, используя для каждого цикла и задач потока данных (от источника до места назначения)

Оба изэти пакеты должны использовать созданный мной файл конфигурации пакета, в котором хранятся имя пользователя и пароль базы данных назначения (база данных Azure, использующая проверку подлинности SQL Server).

Использование этого файла конфигурации прекрасно работает для пакета 1), но когда япопробуйте создать пакет служб SSIS с использованием кода BIML для пакета 2) я получаю следующую ошибку:

Could not execute Query on Connection Dest: SELECT * FROM stg.SalesTaxRate. Login failed for user ''.

я пытался использовать код BIML для пакета 1) и добавление в задачу потока данных, и это, кажется, вызываетта же ошибка - кажется, что при использовании задачи «Выполнение SQL» он может без проблем найти и использовать файл конфигурации, но при использовании задачи «Поток данных» не найдет его.

Скрипт для пакета 1):

<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ template language="C#" tier="2" #>
<#
    string _source_con_string = @"Data Source=YRK-L-101098;Persist Security Info=true;Integrated Security=SSPI;Initial Catalog=AdventureWorks2016";
    string _dest_con_string = @"Data Source=mpl.database.windows.net;Initial Catalog=mpldb;Provider=SQLNCLI11.1;Persist Security Info=True;Auto Translate=False";

    string _table_name_sql = "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"; 

    DataTable _table_names = new DataTable();
    SqlDataAdapter _table_name_da = new SqlDataAdapter(_table_name_sql, _source_con_string);
    _table_name_da.Fill(_table_names);  

#>
<#+ 
public string RowConversion(DataRow Row)
{
    string _ret = "[" + Row["COLUMN_NAME"] + "] " + Row["DATA_TYPE"];


    switch (Row["DATA_TYPE"].ToString().ToUpper())
    {
        case "NVARCHAR":
        case "VARCHAR":
        case "NCHAR":
        case "CHAR":
        case "BINARY":
        case "VARBINARY":
            if (Row["CHARACTER_MAXIMUM_LENGTH"].ToString() == "-1")
                _ret += "(max)";
            else
                _ret += "(" + Row["CHARACTER_MAXIMUM_LENGTH"] + ")";
            break;

        case "NUMERIC":
            _ret += "(" + Row["NUMERIC_PRECISION"] + "," + Row["NUMERIC_SCALE"] + ")";
            break;

        case "FLOAT":
            _ret += "(" + Row["NUMERIC_PRECISION"] + ")";
            break;
    }

    return _ret;
}
#> 

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
  <Connections>
    <OleDbConnection Name="Dest" ConnectionString="Data Source=mpl.database.windows.net;Initial Catalog=mpldb;Provider=SQLNCLI11.1;Persist Security Info=True;Auto Translate=False" /> 
  </Connections>
    <Packages>
        <Package Name="005_Create_Staging_Configuration" ConstraintMode="Linear">

            <PackageConfigurations>
                <PackageConfiguration Name="Configuration">
                    <ExternalFileInput ExternalFilePath="C:\VSRepo\BIML\Configurations\AzureConfigEdit.dtsConfig">
                    </ExternalFileInput>
                </PackageConfiguration>
            </PackageConfigurations>

            <Tasks>
            <Container Name="Create Staging Tables" ConstraintMode="Linear">
                <Tasks>
                    <# foreach(DataRow _table in _table_names.Rows) {    #>           
                    <ExecuteSQL Name="SQL-S_<#= _table["TABLE_NAME"] #>" ConnectionName="Dest">
                        <DirectInput>

                            IF OBJECT_ID('stg.<#= _table["TABLE_NAME"] #>','U') IS NOT NULL
                            DROP TABLE stg.<#= _table["TABLE_NAME"] #>;

                            CREATE TABLE stg.<#= _table["TABLE_NAME"] #>
                            (
                            <#

                                string _col_name_sql = "select COLUMN_NAME, DATA_TYPE,  CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE from INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA='" + _table["TABLE_SCHEMA"] + "' and TABLE_NAME='"+ _table["TABLE_NAME"] + "' order by ORDINAL_POSITION ";

                                DataTable _col_names = new DataTable();
                                SqlDataAdapter _col_names_da = new SqlDataAdapter(_col_name_sql, _source_con_string);
                                _col_names_da.Fill(_col_names);

                                for (int _i=0; _i<_col_names.Rows.Count ; _i++  )
                                {
                                    DataRow _r = _col_names.Rows[_i];

                                    if (_i == 0)
                                        WriteLine(RowConversion(_r));
                                    else
                                        WriteLine(", " + RowConversion(_r));                                
                                }

                            #>
                            , append_dt datetime
                            )
                        </DirectInput>
                    </ExecuteSQL>
                    <# } #>
                </Tasks>
            </Container>
            </Tasks>        
        </Package>
    </Packages>
</Biml>

Сценарий для пакета 2)

<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ template language="C#" tier="2" #>
<#
    string _source_con_string = @"Data Source=YRK-L-101098;Persist Security Info=true;Integrated Security=SSPI;Initial Catalog=AdventureWorks2016";
    string _dest_con_string = @"Data Source=mpl.database.windows.net;Initial Catalog=mpldb;Provider=SQLNCLI11.1;Persist Security Info=True;Auto Translate=False";

    string _table_name_sql = "select  TABLE_SCHEMA , table_name from INFORMATION_SCHEMA.TABLES  where TABLE_TYPE='BASE TABLE'"; 

    DataTable _table_names = new DataTable();
    SqlDataAdapter _table_name_da = new SqlDataAdapter(_table_name_sql, _source_con_string);
    _table_name_da.Fill(_table_names);  

#>

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
  <Connections>
    <OleDbConnection Name="Source" ConnectionString="Data Source=YRK-L-101098;Provider=SQLNCLI11.1;Persist Security Info=true;Integrated Security=SSPI;Initial Catalog=AdventureWorks2016" />
    <OleDbConnection Name="Dest" ConnectionString="Data Source=mpl.database.windows.net;Initial Catalog=mpldb;Provider=SQLNCLI11.1;Persist Security Info=True;Auto Translate=False" />
  </Connections>
    <Packages>
        <Package Name="006_Load_Staging_Configuration" ConstraintMode="Linear">
            <PackageConfigurations>
                <PackageConfiguration Name="Configuration">
                    <ExternalFileInput ExternalFilePath="C:\VSRepo\BIML\Configurations\AzureConfigDF.dtsConfig"></ExternalFileInput>
                </PackageConfiguration>
            </PackageConfigurations>
            <Tasks>
            <Container Name="Load Staging Tables" ConstraintMode="Linear">
                <Tasks>
                    <# foreach(DataRow _table in _table_names.Rows) {    #>     
                    <Dataflow Name="DFT-S_<#= _table["TABLE_NAME"] #>">
                        <Transformations>
                            <OleDbSource Name="SRC-<#= _table["TABLE_SCHEMA"] #>_<#= _table["TABLE_NAME"] #>" ConnectionName="Source">
                                <DirectInput>
                                    SELECT  *
                                    FROM <#= _table["TABLE_SCHEMA"] #>.<#= _table["TABLE_NAME"] #>
                                </DirectInput>
                            </OleDbSource>
                            <OleDbDestination Name="DST-<#= _table["TABLE_SCHEMA"] #>_<#= _table["TABLE_NAME"] #>" ConnectionName="Dest">
                                <ExternalTableOutput Table="stg.<#= _table["TABLE_NAME"] #>"/>
                            </OleDbDestination>
                        </Transformations>
                    </Dataflow>
                    <# } #>
                </Tasks>
            </Container>
            </Tasks>        
        </Package>
    </Packages>
</Biml>

Файл конфигурации:

<?xml version="1.0"?>
<DTSConfiguration>
  <Configuration ConfiguredType="Property" Path="\Package.Connections[Source].Properties[ConnectionString]" ValueType="String">
    <ConfiguredValue>"Data Source=YRK-L-101098;Provider=SQLNCLI11.1;Persist Security Info=true;Integrated Security=SSPI;Initial Catalog=AdventureWorks2016"</ConfiguredValue>
  </Configuration>  <Configuration ConfiguredType="Property" Path="\Package.Connections[Dest].Properties[ConnectionString]" ValueType="String">
    <ConfiguredValue>Data Source=mpl.database.windows.net;User ID=*****;Initial Catalog=mpldb;Provider=SQLNCLI11.1;Persist Security Info=True;Auto Translate=False</ConfiguredValue>
  </Configuration>
  <Configuration ConfiguredType="Property" Path="\Package.Connections[Dest].Properties[Password]" ValueType="String">
    <ConfiguredValue>******</ConfiguredValue>
  </Configuration>
  <Configuration ConfiguredType="Property" Path="\Package.Connections[Dest].Properties[UserName]" ValueType="String">
    <ConfiguredValue>******</ConfiguredValue>
  </Configuration>
</DTSConfiguration>

Примечание : значения для 'UserId' и 'Password'заполнены правильными значениями в реальном скрипте.

1 Ответ

0 голосов
/ 06 июня 2018

Сводка
Проблема заключается в том, что вы пытаетесь использовать конфигурации пакетов (функция времени выполнения служб SSIS) при разработке пакетов, генерируя их с помощью Biml (функция времени сборки).

Что происходит?
Подумайте об этом так.Если вам нужно было вручную создать пакет служб SSIS, во время разработки вам потребуется подключиться к исходной и целевой базам данных, указав имена пользователей и пароли.Без подключения к базам данных SSIS не сможет получить необходимые метаданные.После разработки пакета и сопоставления всех метаданных вы можете использовать конфигурации пакета.Когда вы открываете или запускаете пакет с конфигурациями пакетов, все жестко заданные значения будут заменены значениями конфигурации.Эта замена значения является функцией времени выполнения служб SSIS.

Теперь сравните это с использованием Biml вместо создания пакета SSIS вручную: при создании пакетов вы ожидаете, что механизм Biml получит имена пользователей и паролииз файлов конфигурации пакета.Поскольку это функция времени выполнения служб SSIS, Biml не может получить эти данные и будет использовать строки подключения, указанные в BimlScript.Поскольку в этих строках подключения не указаны имена пользователей и пароли, Biml не сможет подключиться, и вы получите ошибку Ошибка входа пользователя '' .(Это похоже на создание диспетчера соединений в службах SSIS без указания имени пользователя и пароля и получения ошибки при нажатии «Проверить соединение».)

Но это работает для задачи «Выполнение SQL»?
Это может выглядеть так, но это не так.Задача «Выполнение SQL» в основном просто игнорируется.Код SQL в задачах «Выполнение SQL» не проверяется и не проверяется службами SSIS или Biml, пока не будет выполнен пакет.Вы можете ввести что-нибудь там, и SSIS будет рад до тех пор, пока вы не попытаетесь выполнить неверный код, после чего он выдаст вам ошибку.Поскольку этот код не проверяется SSIS во время разработки, он не проверяется Biml во время генерации пакета.Пакет генерируется успешно, а затем, когда вы его откроете, будут применены конфигурации пакета, и вы не увидите никаких ошибок.

Назначение OLE DB, однако, проверяется как службами SSIS, так и механизмом Biml.во время разработки.Им обоим необходимо подключиться к базе данных, чтобы получить метаданные.Вот почему вы получаете сообщение об ошибке только для этого файла.

Решение
Конфигурации пакета являются только функцией времени выполнения служб SSIS.Вы не можете использовать их для передачи строк подключения, имен пользователей или паролей в движок Biml.Вы можете либо жестко закодировать строки подключения в вашем BimlScript, либо сохранить строки подключения во внешнем хранилище метаданных, но вам нужно будет указать имена пользователей и пароли для механизма Biml во время генерации пакета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...