12

Вопроса пост к программистам, датасаянтистам

Товарищи, прошу посильной помощи, подсказки профи и умельцев во имя научения.


Добрый день.

"Напоролся" на ситуацию впервые, но, как я понимаю, для специалистов по BigData - вполне частая ситуация.

Хотел попробовать поработать с большим массивом данных на основе информации на портале ГосЗакупок. Данных очень много, потому показалось интересным, в том числе, в учебных целях.

Power BI не умеет работать с ftp, где расположены данные, потому пришлось искать варианты решения. Остановился на написании bat-файла, который загружает обновлённые данные c ftp на жёсткий и может обновлять: (код bat-файла, если вдруг интересно)


@Echo off

set downloadfolder="fcs_regions/Permskij_kraj/contracts/"

IF not exist %downloadfolder% (mkdir %downloadfolder%)

"C:\Program Files (x86)\WinSCP\WinSCP.com" ^

/log="D:\Code\M + DAX\ftp.zakupki.gov.ru\scp_sync_log.txt" /ini=nul ^

/command ^

"open ftp://free:free@ftp.zakupki.gov.ru/" ^

"synchronize -criteria=size -transfer=binary local ""d:\Code\M + DAX\ftp.zakupki.gov.ru\%downloadfolder%"" %downloadfolder%" ^

"close" ^

"exit"

set WINSCP_RESULT=%ERRORLEVEL%

if %WINSCP_RESULT% equ 0 (

echo Success

) else (

echo Error

)

exit /b %WINSCP_RESULT%


Всё стало лучше (так казалось), настало время подключаться к данным (а это данные, если вдруг захотите получить готовый комплект). Сформировал 3 файла: общий путь к данным, функция вы извлечения данных из архивов, набор операций преобразования данных.

В общем-то и всё. Начинаем грузить информацию. К слову говоря, делаем это на сервере, где выделяется 36 Гб оперативки и достаточная производительная мощность. Однако, в процессе загрузки (а это только часть данных) всё крашится с неведомыми ошибками. Я полагаю, что просто ресурсов не хватает. Шутка ли, загрузить в кеш 20 Гб данных в виде архивов, каждый из которых надо распаковать и всё это ещё и объединить и прочее.

Собственно, теперь вопрос. Как построить работу с таким объёмом данных и умудриться это всё обработать?


let

Источник = Folder.Files(#"Путь к папке"),

#"Полный путь к файлу" = Table.AddColumn(Источник, "Полный путь к файлу", each [Folder Path]&[Name]),

#"Другие удаленные столбцы" = Table.SelectColumns(#"Полный путь к файлу",{"Полный путь к файлу"}),

#"Измененный тип" = Table.TransformColumnTypes(#"Другие удаленные столбцы",{{"Полный путь к файлу", type text}}),

#"Контент фалйа" = Table.AddColumn(#"Измененный тип", "Контент файла", each File.Contents ([Полный путь к файлу])),

#"Вызвана настраиваемая функция" = Table.AddColumn(#"Контент фалйа", "fx_UnzipContents", each fx_UnzipContents([Контент файла])),

#"Проверка целостности" = Table.AddColumn(#"Вызвана настраиваемая функция","IsEmpty", each Table.IsEmpty([fx_UnzipContents])),

#"Строки с примененным фильтром" = Table.SelectRows(#"Проверка целостности", each ([IsEmpty] = false)),

#"Развернутый элемент fx_UnzipContents" = Table.ExpandTableColumn(#"Строки с примененным фильтром", "fx_UnzipContents", {"FileName", "Content"}, {"FileName", "Content"}),

#"Исключение не xml" = Table.SelectRows(#"Развернутый элемент fx_UnzipContents", each (Text.End([FileName],4) = ".xml")),

#"Добавлен пользовательский объект" = Table.AddColumn(#"Исключение не xml", "Содержание XML", each Xml.Tables([Content])),

#"Развернутый элемент Содержание XML" = Table.ExpandTableColumn(#"Добавлен пользовательский объект", "Содержание XML", {"Name", "Table"}, {"Name", "Table"}),

#"Развернутый элемент Table" = Table.ExpandTableColumn(#"Развернутый элемент Содержание XML", "Table", {"http://zakupki.gov.ru/oos/types/1", "Attribute:schemeVersion"}, {"http://zakupki.gov.ru/oos/types/1", "Attribute:schemeVersion"}),

#"Другие удаленные столбцы1" = Table.SelectColumns(#"Развернутый элемент Table",{"http://zakupki.gov.ru/oos/types/1"}),

#"Развернутый элемент http://zakupki.gov.ru/oos/types/1" = Table.ExpandTableColumn(#"Другие удаленные столбцы1", "http://zakupki.gov.ru/oos/types/1", {"id", "regNum", "number", "publishDate", "signDate", "versionNumber", "foundation", "customer", "protocolDate", "documentBase", "price", "currency", "singleCustomerReason", "executionDate", "finances", "products", "suppliers", "href", "printForm", "scanDocuments", "currentContractStage"}, {"id", "regNum", "number", "publishDate", "signDate", "versionNumber", "foundation", "customer", "protocolDate", "documentBase", "price", "currency", "singleCustomerReason", "executionDate", "finances", "products", "suppliers", "href", "printForm", "scanDocuments", "currentContractStage"}),

#"Развернутый элемент customer" = Table.ExpandTableColumn(#"Развернутый элемент http://zakupki.gov.ru/oos/types/1", "customer", {"regNum", "fullName", "inn", "kpp"}, {"customer.regNum", "customer.fullName", "customer.inn", "customer.kpp"}),

#"Развернутый элемент currency" = Table.ExpandTableColumn(#"Развернутый элемент customer", "currency", {"code", "name"}, {"currency.code", "currency.name"}),

#"Развернутый элемент executionDate" = Table.ExpandTableColumn(#"Развернутый элемент currency", "executionDate", {"month", "year"}, {"executionDate.month", "executionDate.year"}),

#"Развернутый элемент singleCustomerReason" = Table.ExpandTableColumn(#"Развернутый элемент executionDate", "singleCustomerReason", {"id", "name"}, {"singleCustomerReason.id", "singleCustomerReason.name"}),

#"Удаленные столбцы" = Table.RemoveColumns(#"Развернутый элемент singleCustomerReason",{"printForm", "scanDocuments"}),

#"Развернутый элемент foundation" = Table.ExpandTableColumn(#"Удаленные столбцы", "foundation", {"oosOrder"}, {"foundation.oosOrder"}),

#"Развернутый элемент foundation.oosOrder" = Table.ExpandTableColumn(#"Развернутый элемент foundation", "foundation.oosOrder", {"notificationNumber", "lotNumber", "placing"}, {"foundation.oosOrder.notificationNumber", "foundation.oosOrder.lotNumber", "foundation.oosOrder.placing"}),

#"Развернутый элемент suppliers" = Table.ExpandTableColumn(#"Развернутый элемент foundation.oosOrder", "suppliers", {"supplier"}, {"suppliers.supplier"}),

#"Развернутый элемент suppliers.supplier" = Table.ExpandTableColumn(#"Развернутый элемент suppliers", "suppliers.supplier", {"participantType", "inn", "kpp", "organizationName", "country", "factualAddress", "postAddress", "contactPhone"}, {"suppliers.supplier.participantType", "suppliers.supplier.inn", "suppliers.supplier.kpp", "suppliers.supplier.organizationName", "suppliers.supplier.country", "suppliers.supplier.factualAddress", "suppliers.supplier.postAddress", "suppliers.supplier.contactPhone"}),

#"Развернутый элемент suppliers.supplier.country" = Table.ExpandTableColumn(#"Развернутый элемент suppliers.supplier", "suppliers.supplier.country", {"countryCode", "countryFullName"}, {"suppliers.supplier.country.countryCode", "suppliers.supplier.country.countryFullName"}),

#"Развернутый элемент finances" = Table.ExpandTableColumn(#"Развернутый элемент suppliers.supplier.country", "finances", {"financeSource", "extrabudget", "extrabudgetary"}, {"finances.financeSource", "finances.extrabudget", "finances.extrabudgetary"}),

#"Развернутый элемент finances.extrabudget" = Table.ExpandTableColumn(#"Развернутый элемент finances", "finances.extrabudget", {"code", "name"}, {"finances.extrabudget.code", "finances.extrabudget.name"}),

#"Развернутый элемент finances.extrabudgetary" = Table.ExpandTableColumn(#"Развернутый элемент finances.extrabudget", "finances.extrabudgetary", {"month", "year", "substageMonth", "substageYear", "KOSGU", "price"}, {"finances.extrabudgetary.month", "finances.extrabudgetary.year", "finances.extrabudgetary.substageMonth", "finances.extrabudgetary.substageYear", "finances.extrabudgetary.KOSGU", "finances.extrabudgetary.price"}),

#"Развернутый элемент products" = Table.ExpandTableColumn(#"Развернутый элемент finances.extrabudgetary", "products", {"product"}, {"products.product"}),

#"Развернутый элемент products.product" = Table.ExpandTableColumn(#"Развернутый элемент products", "products.product", {"sid", "OKPD", "name", "OKEI", "price", "quantity", "sum"}, {"products.product.sid", "products.product.OKPD", "products.product.name", "products.product.OKEI", "products.product.price", "products.product.quantity", "products.product.sum"}),

#"Развернутый элемент products.product.OKPD" = Table.ExpandTableColumn(#"Развернутый элемент products.product", "products.product.OKPD", {"code", "name"}, {"products.product.OKPD.code", "products.product.OKPD.name"}),

#"Развернутый элемент products.product.OKEI" = Table.ExpandTableColumn(#"Развернутый элемент products.product.OKPD", "products.product.OKEI", {"code", "nationalCode"}, {"products.product.OKEI.code", "products.product.OKEI.nationalCode"})

in

#"Развернутый элемент products.product.OKEI"


А это на случай, если захотите посмотреть мой файлик.

MS, Libreoffice & Google docs

782 поста15K подписчиков

Правила сообщества

1. Не нарушать правила Пикабу

2. Публиковать посты соответствующие тематике сообщества

3. Проявлять уважение к пользователям

4. Не допускается публикация постов с вопросами, ответы на которые легко найти с помощью любого поискового сайта.

По интересующим вопросам можно обратиться к автору поста схожей тематики, либо к пользователям в комментариях


Важно - сообщество призвано помочь, а не постебаться над постами авторов! Помните, не все обладают 100 процентными знаниями и навыками работы с Office. Хотя вы и можете написать, что вы знали об описываемом приёме раньше, пост неинтересный и т.п. и т.д., просьба воздержаться от подобных комментариев, вместо этого предложите способ лучше, либо дополните его своей полезной информацией и вам будут благодарны пользователи.

Утверждения вроде "пост - отстой", это оскорбление автора и будет наказываться баном.

Автор поста оценил этот комментарий

А что на профильных ресурсах забанили?

раскрыть ветку (1)
2
Автор поста оценил этот комментарий

Нет, просто здесь охват шире...и сообщество тоже соответствующее.

10
Автор поста оценил этот комментарий

Тезисно:

- Если падают неведомые ошибки, то нужно их прочитать, понять и действовать в зависимости от ошибки

- 20 ГБ - это даже не рядом с BigData. BigData - это когда хотя бы терабайт.

- Никто в здравом уме не работает в памяти с XML (или JSON) такого объёма. Это транспортный формат. Первое, что нужно сделать - это залить его в базу, например в реляционную. Делать это нужно не в памяти, а поточной трансформацией через какой-нибудь SAX или готовым приложением, которое такое умеет.

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Спасибо за совет, буду пробовать

3
Автор поста оценил этот комментарий

Не совсем понял в деталях задумку, ну да ладно. Загрузка с фтп крашить не может, там в оперативку идёт маленькими кусочками и сразу ложится на диск, распаковка архива работает также кусочками. Остаётся обработка xml файла. Судя по всему, как раз тут сие творенье и пытается сразу делать все в оперативке. Так нельзя. Можно кодом на c# (кажется класс называется xml reader, тоже читает кусочками) загнать в любую БД, скажем mssql dev. Edition (бесплатный). И из неё powerbi, как уже из родной бд все построит. И вот все подобное счастье строится как правило в ssis - проекте.

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Отличный совет, почитаю, спасибо.

0
Автор поста оценил этот комментарий

прикольно... вы с фэтэпэ же ресурса данные забираете? винцп - самое то для этого. штатный виндовый ftp-клиент же для этого никак (особенно, если с ключиком -s).

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

А я не умею(( Отментори меня плиз! Что и как предлагаешь?

показать ответы
0
Автор поста оценил этот комментарий

а разве wincp - штатное? впрочем, если работает, то не заморачивайтесь.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий
Я был бы очень благодарен за пример в вашем стиле... если потратите время и покажете , было бы чудесно.
показать ответы
0
Автор поста оценил этот комментарий

если про "штатный" ftp - так там уметь нечего. в cmd (или win-r) запускаешь ftp. вводите команды, которые у вас в скрипте для вин-цп.  убеждаетесь, что все ок. сохраняете в текст. потом в батнике "ftp -s:ваш_ваш_файл". должно взлететь.

с павершел тоже просто: https://www.google.com/search?q=powershell%20ftp%20request

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

хм...хм....  а чём тогда разница с моим решением, не понял... у меня вроде как тоже штатными средствами всё, нет? (тут я поплыл, не разбираюсь сильно)

показать ответы
0
DELETED
Автор поста оценил этот комментарий

Если там данные в формате xml и файлы большие - вам никакой оперативки не хватит с ними работать! Нужно трансформировать их в что-то плоское, типа csv. Делать это нужно при помощи xslt.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Понял, почитаю. Спасибо.

0
Автор поста оценил этот комментарий
Чтоб с батниками не пердолиться, можно использовать rclone, sync2go
раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Пожалуйста, расскажи подробней! Я не знаю что это! Научи немного... плиз

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества