Невозможно сгенерировать BIML-сценарий для Tiering в SSIS - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть ситуация, когда мой главный biml генерирует 150 задач пакета «Выполнить». Мне нужно сгенерировать контейнеры последовательности, чтобы каждый из них содержал (150/10) 15 Выполнить задачу пакета для каждого контейнера последовательности в главном пакете.

Не могли бы вы помочь мне найти подходящее решение, любые идеи / Рабочие примеры / кодовая база приветствуются !!

<Tasks> 
    <# foreach (var package in RootNode.Packages) { #> 
         <ExecutePackage Name="Execute <#=package.Name#>" > 
              <ExternalProjectPackage Package="<#=package.PackageFileName#>" /> 
         </ExecutePackage>
    <# } #>
</Tasks> 

1 Ответ

0 голосов
/ 20 февраля 2019

В этом ответе будут использованы несколько передовых концепций с Biml.Первый будет многоуровневым, поэтому мы сгенерируем 150 пакетов на уровне 1. Затем на уровне 2 (или любом количестве, превышающем предыдущий уровень), мы сможем ссылаться на плоды нашего труда на уровне 0 до (уровень max -1).

Уровень 0 является статическим / плоским Biml (которого у нас нет в этом примере).Поскольку мы будем создавать циклы для создания дочерних пакетов, он автоматически перейдет на уровень 1, но я решил указать это в явном виде на случай, если у вас есть предшествующие, но динамические задачи для решения

<#* .... #> - это суперМощная конструкция комментария, игнорируемая компилятором Biml

<#+ .... #>, предназначена для добавления явных методов и классов в ваш Biml

. Мы также будем использовать метод расширения дляПримерно разделить наши пакеты на группы, чтобы затем поместить их в контейнеры последовательностей.

Уровень 1

Этот код генерирует пустые пакеты служб SSIS с именами в диапазоне от so_54773502_000 до so_54773502_149 (всего 150)

<#@ template tier="1" #>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Packages>
<#foreach (int index in Enumerable.Range(0, 150)){#>
    <Package Name="so_54773502_<#= string.Format("{0:000}", index) #>" />
<#}#>
    </Packages>
</Biml>

Уровень 2

Здесь мы указываем, сколько параллельных контейнеров мы хотим.Результатом метода Split является список списков.Для каждого элемента во внешнем списке контейнеров нам нужно добавить контейнер последовательности.Для каждого элемента в этом всплывающем списке нам нужно перечислить его и выполнить задачу пакета.

<#@ template tier="2" #>
<#
int taskCountPerContainer = 10;
int currentContainerNumber = 0;
#>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Packages>
        <Package Name="master">
            <Tasks>
<#* 
    This is such a fun bit of LINQ. I used the Split extension so handily defined on the linked question
    I pass in a List of package names and how many buckets I want and it returns a list of lists

    From there, we enumerate through the list bucket and for each element we find, we create a sequence
    container. Then, for each element in the bucket, we add an Execute Package Task.

    I was unable to Split an instance of AstPackageNodes as it resulted in the error below but the only reason
    your sample needed the full object was to provide both Name and PackageFileName properties. We can derive
    the second given the first

// foreach(var outerlist in Split(this.RootNode.Packages.ToList<AstPackageNode>(),taskCountPerContainer)){    
// results in this error. 
// Destination array was not long enough. Check destIndex and length, and the array's lower bounds.    
// TODO: Check with Varigence or run in C# project

*#>
                <#foreach(var listOfPackages in Split(this.RootNode.Packages.Select(x => x.Name).ToList<string>(), taskCountPerContainer)){#>
                <Container Name="SEQC_<#=currentContainerNumber++#>" ConstraintMode="Linear">
                    <Tasks>
                    <#foreach(var packageName in listOfPackages){#>
                        <ExecutePackage Name="EPT <#=packageName#>"><ExternalProjectPackage Package="<#=packageName#>.dtsx"/></ExecutePackage>
                    <#}#>
                    </Tasks>
                </Container>
                <#}#>
            </Tasks>
        </Package>
    </Packages>
</Biml>

<#+
// /381429/razdelit-spisok-na-podspiski-s-pomoschy-linq
public static IList<List<T>> Split<T>(IList<T> source, int buckets)
{
    return  source
        .Select((x, i) => new { Index = i, Value = x })
        .GroupBy(x => x.Index / buckets)
        .Select(x => x.Select(v => v.Value).ToList())
        .ToList();
}

#>

Конечный результат

Смотри, много пакетов выполняется!

enter image description here

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