Comments 25
Подскажите — а можете добавить поддержку ODBC, для использования любых SQL БД?
Когда-нибудь перенесу тот функционал в ImportExportDataSql
Уважаемый автор, спасибо во-первых.
Во-вторых вопрос: где то раз в квартал приходится заниматься одной странной хренью — качать с одного гос.сайта гигантский XML (2-3 гига) с чудовищной структурой, которую распарсить в csv без падения может лишь одна утилитка (не важно какая, в итоге csv).
Далее этот csv я должен импортировать через "Import and Export Data (64-bt)" с полной перезаписью в таблицу.
Т.к. длина текстовых полей велика и заголовки полей периодически могут "плавать" написал сам для себя инструкцию чтобы печаль нет так сильно меня брала.
один из хаков по инструкции — согласно совету stack вручную выкручивать длину поля до 8000 символов.
В общем там так себе мастер (хотя раз в квартал терпимо).
Есть ли смысл тратить время на тест Вашего изделия, будет ли оно удобнее для таких задач?
С другой стороны — если всего 1 раз в квартал парсится файл, то можно и костылями решить вопрос.
Берется linq2db
Берется любая библиотека которая CSV парсит и потоково возвращает IEnumerable<string[]>, тут я не помощник.
И пишется что-то такое
var csvItems = CSVParser.Parse("filename");
using (var db = new DataConnection(...))
{
db.BulkCopy(
csvItems.Select(csv => new DestinationEntity{
Field1 = int.Parse(csv[0]),
Field2 = double.Parse(csv[1]),
LongStr = csv[2],
...
})
);
}
Гарантирую, что если отключите индексы, данные влетят, даже чай не успеете заварить.
Для баз данных, которые поддерживают такие вставки, и того быстрее. Будут посланы параметризированные запросы и не надо беспокоиться о длине полей.
Это проверено личным опытом.
P.S.: Даже системная утилита bcp пишет блоками по 1000 записей, не задумывались почему? Правда bcp фиксирует изменения одной транзакцией и это происходит долго (забивается диск), а ImportExportDataSql фиксирует изменения сразу после записи блока.
Вы пропустили мое описание что данные должны представляться как IEnumerable — это не все записи сразу, ни в коем случае.
var csvItems = CSVParser.Parse("filename");
Этот код означает чтение всего файла целиком или частями? Если целиком, то будет System.OutOfMemoryException, а если частями то нужно весь код внести в цикл, чтобы записи из файла считывались блоками.
public IEnumerable<string[]> ParseCsv(string fileName)
{
using (var file = new System.IO.StreamReader(fileName))
{
string line;
while((line = file.ReadLine()) != null)
{
yield return line.Split(‘\t’);
}
}
}
linq2db внутри считывает из этого энумератора только 1000 записей и запихивает это в BulkCopy (для MSSQL) или готовит компактный SQL с параметрами на всю 1000 записей. Объекты больше не нужны и их подберет GC.
Процесс повторяется пока до конца файла не дойдем. Энумератор диспозится и файл закрывается.
Точно также можно взять данные IEnumerable из одной базы и закинуть в другую. Не важно сколько записей в исходной таблице, хоть миллионы.
Если нет, то тогда linq2db будет ждать, пока не прочитается весь файл и при большом объеме файла приложению может не хватить памяти.
Я бы советовал подучить эту часть.
Как только, кто-то начинает энумерацию, создается стейт машина (класс в который превращается ParseCsv метод компилятором) и при вызове метода Next в энумераторе из файла читается одна линия, не больше. Когда файл заканчивается Next вернет false — все мы перебрали все линии.
Нет планов пустить приложение в open-source, чтобы сообщество могло предлагать свои доработки?
Но объективно — велосипед же?) Есть уже написанные проф. среды для визуальной разработки ETL-процедур. Talend вообще бесплатен и функциональность на несколько порядков выше. Разворачивается за 10 минут и еще минут за 10 выкачивает всякие доп.библиотеки. Явно меньше времени, чем на написание вашего тула ушло. А скомпилированный .jar ETL-процедуры можно хоть в cron выполнять, хоть любым win scheduler.
Если продукт бесплатный, то предлагаю выложить код и сам проект в GitHub или в GitLab.
Как на это смотрите?
https://www.zamzar.com/convert/csv-to-mdb/
Кириллица полегла, но парсил избыточную выжимку с госсайта. Достаточно госсловарей и UID на них
ImportExportDataSql — бесплатный конвертер данных MSSQL