Лучшая практика для заполнения статических данных с помощью проекта базы данных Visual Studio 2010?

Как заполнить базу данных статическими данными с контролируемым исходным кодом с помощью проекта базы данных Visual Studio? Я испробовал все три приведенные ниже стратегии и обнаружил, что каждая из них все лучше предыдущей. Я использую, но не полностью удовлетворен стратегией 3. У вас есть другая альтернатива?

  1. Поместите скрипты вставки в папку «Планы генерации данных». Сошлитесь на сценарии в файле «Script.PostDeployment.sql», чтобы включить их в процесс развертывания.

    -- преимущество: простота
    -- недостаток: медлительность
    -- недостаток: последующие развертывания должны сначала удалять статические данные или проверять отсутствие данных => неэффективно

  2. Вставьте данные в базу данных в первый раз, используя наиболее удобный метод (например, это может быть функция редактирования таблицы SSMS). Извлеките эти данные с помощью утилиты командной строки bcp, чтобы создать набор файлов данных и добавить их в свой проект. Создайте сценарий, указанный в файле «Scripts.PostDeployment.sql», который выполняет оператор «массовой вставки» для каждого файла данных.

    -- Преимущество: намного быстрее, чем операторы вставки
    -- Преимущество: можно использовать функцию редактирования таблицы SSMS
    -- Недостаток: каждый оператор массовой вставки требует полного имени файла для файла данных, поэтому, если файлы данных расположены на моем компьютере в "C:\Projects\Dev\Source\foo.dat", то удаленный компьютер разработчика также должен иметь их в этом месте, иначе оператор массовой вставки завершится ошибкой
    -- недостаток: необходимо удалить существующие статические данные перед выполнением операторы массовой вставки при последующих развертываниях

  3. Создайте временные таблицы во время развертывания для хранения статических данных и используйте оператор слияния sql для синхронизации этих таблиц с целевыми таблицами. См. либо из этих сообщений в блоге.

    -- Преимущество: кажется, что семантика SQL-слияния идеально подходит для решения проблемы
    -- Недостаток: логика этой стратегии повторяется в каждом файле -- Недостаток: определения таблиц повторяются как временные таблицы в файлах слияния SQL.

Существует ли лучшая альтернативная стратегия? Я отказался от стратегии 1, потому что она была слишком медленной. Мне не нравится стратегия 2 из-за проблемы с полным именем файла. Я удовлетворен, но не в восторге от стратегии 3. Есть ли передовой опыт?


person Tim Partridge    schedule 25.11.2010    source источник
comment
Есть ли у вас возможность оставить данные в целевой базе данных, а не заполнять ее каждый раз заново?   -  person David Atkinson    schedule 29.11.2010
comment
@David: я не верю, что есть такой вариант, если только кто-то не скажет мне обратное. Это должно быть частью скриптового решения. Стратегия 3 обрабатывает это с помощью команды слияния. Стратегию 1 необходимо изменить, чтобы сначала проверить, существуют ли данные перед вставкой. Аналогично для стратегии 2.   -  person Tim Partridge    schedule 29.11.2010
comment
Вероятно, это вас не утешит, но мы только что выпустили SQL Source Control 2, который поддерживает статические данные. К сожалению, это не поддерживает проект базы данных - по крайней мере, пока. Тем не менее, мы серьезно рассматриваем это. Если вы заинтересованы, пожалуйста, проголосуйте здесь: redgate.uservoice.com/forums/39019-sql-source-control/   -  person David Atkinson    schedule 12.03.2011
comment
Для стратегии 1 «медленнее» — это мягко сказано. В данный момент я работаю над новым проектом. Начал просто работать с созданием БД и данными по умолчанию. Я перешел к проекту БД, чтобы стремиться к лучшему способу обслуживания материалов БД, но теперь я чувствую, что ручной запуск скриптов был проще, просто потому, что он очень медленный в развертывании, и, как вы сказали, вы должны сначала вручную проверить наличие, если вы хотите запустить данные в сценарии после развертывания и сделать их идемпотентными.   -  person jamiebarrow    schedule 18.03.2011


Ответы (4)


В вашем скрипте insert.sql вы можете поместить GUID в таблицу [__RefactorLog] (которая является системной таблицей, используемой при развертывании) и проверить, существует ли этот GUID, прежде чем вставлять свои данные следующим образом:

:setvar SOMEID "784B2FC9-2B1E-5798-8478-24EE856E62AE"//создать руководство с помощью Tools\CreateGuid в VS2010

ЕСЛИ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ [OperationKey] FROM [dbo].[__RefactorLog], где [OperationKey] = '$(SOMEID)')

НАЧИНАТЬ

...

INSERT INTO [dbo].[__RefactorLog] ([OperationKey]) values( '$(SOMEID)')

КОНЕЦ

Затем вы вставляете данные, только если они не существуют или если вы хотите (путем изменения Guid).

person j0n    schedule 08.03.2011

Вот как я решил эту проблему, если кто-то еще найдет это полезным...

Стратегия заключается в установке переменной sqlcmdvars перед построением проекта базы данных. Эта переменная будет содержать абсолютный путь к папке сборки, на которую можно ссылаться из сценария после развертывания. Тогда было бы просто использовать это в сценарии развертывания для любых дополнительных файлов или ресурсов, которые могут вам понадобиться. Преимущество этой стратегии заключается в том, что все пути относятся к файлу проекта, а не требуют жестко закодированного общего пути.

Создайте новое имя переменной команды Sql $(MSBuildProjectDirectory). Это будет переопределено в сценарии предварительной сборки.

Создайте сценарий msbuild, который установит переменную команды sql и создаст базу данных.

<Project ToolsVersion="4.0" DefaultTargets="BuildDatabase"  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
    <DatabaseServer>(Local)</DatabaseServer>
    <DeploymentConnectionString>Data Source=$(DatabaseServer)%3BIntegrated Security=True%3BPooling=False</DeploymentConnectionString>
    <Configuration>Release</Configuration>
</PropertyGroup>
<Target Name="BuildDatabase">
    <!-- Sets the projet path variable so that the post deployment script can determine the location of the bulk insert csv files. -->
    <XmlUpdate
        Prefix="urn"
        Namespace="urn:Microsoft.VisualStudio.Data.Schema.Package.SqlCmdVars"
        XmlFileName="$(MSBuildProjectDirectory)\DatabaseProjectName\Properties\Database.sqlcmdvars"
        XPath="/urn:SqlCommandVariables/urn:Properties/urn:Property[urn:PropertyName='MSBuildProjectDirectory']/urn:PropertyValue"
        Value="$(MSBuildProjectDirectory)\DatabaseProjectName" />

    <MSBuild
            Projects="DatabaseProjectName\DatabaseProjectName.dbproj"
            Properties="Configuration=$(Configuration);
                    TargetDatabase=DatabaseName;
                    TargetConnectionString=$(DeploymentConnectionString);
                    GenerateDropsIfNotInProject=True;
                    BlockIncrementalDeploymentIfDataLoss=False;
                    DeployToDatabase=True;
                    IgnorePermissions=True"
            Targets="Build;Deploy">
        <Output TaskParameter="TargetOutputs" ItemName="SqlFiles"/>
    </MSBuild>
</Target>

Update your post deployment script as follows...

BULK INSERT [dbo].[TableName] FROM '$(MSBuildProjectDirectory)\Scripts\Post-Deployment\Data\YourDataFile.csv'
WITH (FIELDTERMINATOR = ',', ROWTERMINATOR='\n')
person Jason Turan    schedule 29.11.2013

Вы можете использовать вывод схемы из проекта базы данных для обновления целевой базы данных. Существует инструмент cmd для запуска его на другом компьютере, который не подходит для вас vs2010 IDE.

Таким образом, ваши данные останутся прежними, если только у вас нет капель в каком-либо столбце.

person Darrell    schedule 05.05.2011

Мы еще не перевели наш проект VS 2010 db в производственную среду, но для нашего внутреннего проекта мы загружаем производственную базу данных в целевую базу данных и собираем/развертываем ее на этапе разработки/тестирования. Тем не менее, я понимаю, что Тим, вероятно, не сработает для вас, если у вас есть несколько баз данных prod и статические данные, которые выходят в каждую. Но это можно сделать для отдельных магазинов prod db, таких как наш.

person vkirkpat    schedule 28.02.2011
comment
Спасибо за ответ. Не могли бы вы дать мне немного больше деталей? Итак, вы делаете резервную копию продукта, восстанавливаете его в цель (следовательно, цель имеет все данные), а затем запускаете развертывание из VS для синхронизации схем? Если это правда, то кажется, что вы не можете запретить кому-либо добавлять данные в продукт, который затем будет распространяться на цель. Я ищу способ с контролем источника сказать: это наши базовые данные, и после того, как я нажму «Развернуть», я уверен, что они существуют в цели. Следовательно, тот же метод также будет поддерживать: Вот набор данных, который формирует тестовый пример, который можно многократно развертывать. - person Tim Partridge; 01.03.2011