Вход | Регистрация
    1  2  3  4   
1С:Предприятие :: 1С:Предприятие 7.7 и ранее

v7: Необходим быстрый поиск информации в больших CSV файлах

v7: Необходим быстрый поиск информации в больших CSV файлах
Я
   evgpinsk_
 
01.05.21 - 13:07
Есть прайс в формате CSV площадки onliner.by
В нём 700 тыс позиций.
Раз в сутки прайс обновляется.

Стоит задача в 1с получать быстрый доступ к цене определённого товара из данного прайса (скорость желательна в пределах нескольких секунд).
В прайсе есть столбец "IDтовара" по которому будет осуществляться поиск.

Вопрос: Каким образом осуществлять поиск, через какие инструменты?
 
 Партнерская программа EFSOL Oblako
   acanta
 
101 - 08.05.21 - 18:47
Там еще авто сохранение было.
В сдх индексы все в одном файле, а в фокспро в отдельных.
   Djelf
 
102 - 08.05.21 - 20:29
(96) Интерфейс это ерунда, при рабочем решении!
Кирпич нарисовал индекс, для этого, частного случая, в отдельном csv файле.
Этот вариант вполне работоспособен, 1С же же в 3й версии индексов своих логов подобный и применила.
И он должен быть быстрее раз в 10-100 любой конвертации в сторониие форматы!
   Кирпич
 
103 - 08.05.21 - 20:38
(102) Не очень работоспособен. Чота ADO Stream кажись грузит весь файл в память и читать строку не получатся. Пускай уже грузит в dbf :) Разве что грузилку в dbf написать в отдельном exe(ради быстродействия)
   acanta
 
104 - 08.05.21 - 21:02
Так к концу года глядишь и файловую версию 1с 8.3 на прямые запросы можно будет...
   acanta
 
105 - 08.05.21 - 21:03
Простите за глупые вопросы, у них что, файловая база в csv, а индексные файлы в кеше?
   Вафель
 
106 - 08.05.21 - 22:26
В любом случае чтобы получить строку по номеру нужно весь файл в память загрузить
   Вафель
 
107 - 08.05.21 - 22:26
И каждый раз придётся это заново делать для каждого юзера
   Garykom
 
108 - 08.05.21 - 22:49
(106) Зачем? Можно же файл считывать с нужной позиции символов-байт
Но да надо иметь внешний индекс с какой позиции нужная строка и длина строки
   evgpinsk_
 
109 - 09.05.21 - 00:30
(102) Не совсем понял смысл использования скрипта exe для разделения одного большого CSV файла на два маленьких. Ведь всёравно для поиска данные нужно закинуть или в DBF или в другую баду данных, где через индекс можно будет производить быстрый поиск
   Garykom
 
110 - 09.05.21 - 00:46
(109) Хочешь тупую идею?
Совсем тупую но вполне рабочую.

Банально одним проходом подели свой csv на 700 тысяч файлов, в каждом одна строка
А имя файла это твой id по которому искать будет банально, просто прочитать файл с этим именем
   Garykom
 
111 - 09.05.21 - 00:47
(110)+ Тут конечно ограничение файловой системы может всплыть но маловероятно, миллионы вроде там ограничения файлов если не больше в одном каталоге
   evgpinsk_
 
112 - 09.05.21 - 00:58
(110) По большому счёту любой формат хранения данных подходит, который позволяет искать через индекс.
Я уже реализовал построчное чтение xlsx в dbf через ADODB
Читать сразу CSV файл через ADODB у меня не получилось, и есть неудобная ручная операция - сохранение CSV в XLSX
   Garykom
 
113 - 09.05.21 - 01:49
(112) Операции со строками и текстовыми файлами самые быстрые
Это так к сведению
Поэтому просто попробуй (110)
   Кирпич
 
114 - 09.05.21 - 10:01
(106) Не строку по номеру, а смещение строки в файле. Но это работает, если есть средства перемещения по файлу.
Ну как бы эта задача решается загрузкой в дбф трёх полей. Просто с толку сбило недельное сидение автора над задачей. Я уж подумал ему все данные нужны или медленно работает или хрен знает почему он не хочет тупо грузить в дбф.
   trdm
 
115 - 09.05.21 - 10:07
(112) Кажется есть провайдер, который может прямо из csv читать.
и не нужна прокладка.
https://www.connectionstrings.com/textfile/
   Garykom
 
116 - 09.05.21 - 10:25
(114) просто ТС не программист а не пойми что
над смешной задачкой которая за пару-тройку часов решается сидит хз сколько
   evgpinsk_
 
117 - 09.05.21 - 11:42
(116) А все кто задаёт вопросы на мисте должны быть программистами, а если нет значит - "не пойми что" ?
п.с. в (110) было менее глупо
   acanta
 
118 - 09.05.21 - 11:48
Еще раз для программистов. В 7.7 дбф версии иногда случались сбои. Чаще всего они исправлялись методом переиндексации. В sql версии этих проблем не было.
В 8 ке как версии файловой, так и серверной случаются сбои и они чаще всего исправляются чисткой кэша. Следует ли из этого вывод, что в кэше 1с8 хранятся индексы  или какая то их часть, как в файловой так и в серверной версии?
   Djelf
 
119 - 09.05.21 - 12:17
В продолжение поста в (30). 
260мб csv -> 312мб sqlite, меньше минуты требуется
SELECT load_extension('sqlite3_mod_csv','sqlite3_extension_init');
DROP TABLE IF EXISTS vtPrice;
CREATE VIRTUAL TABLE vtPrice USING csvfile('d:\temp\price\catalog_prices_2021-05-08_13_05_50.csv',0,1);
ATTACH  'd:\temp\price\catalog_prices_2021-05-08_13_05_50.db3' as Price;
DROP TABLE IF EXISTS Price.Price;
CREATE TABLE Price.Price AS SELECT * FROM vtPrice;
-- 49000 мс 
SELECT * FROM Price.Price WHERE c3='2326434' LIMIT 1;
-- 530мс
CREATE UNIQUE INDEX IF NOT EXISTS Price.idxCode ON Price (c3);
-- 1600 мс
SELECT * FROM Price.Price WHERE c3='2326434';
-- -12 мс

   dmitryds
 
120 - 09.05.21 - 12:23
(0) вот это срач... а всего лишь один запрос сделать, как написано в (1)
https://docs.microsoft.com/ru-ru/sql/t-sql/statements/bulk-insert-transact-sql?view=sql-server-ver15
   trdm
 
121 - 09.05.21 - 14:21
(120) не, в данном случае хрень.
   trdm
 
122 - 09.05.21 - 14:25
(118) >  В sql версии этих проблем не было.

повезло тебе, а у меня раз SQL БД навернулась. С тех пор новые документы выгружаю сразу после записи..
   Sysanin_1ц
 
123 - 09.05.21 - 14:46
(0) Панду ТС никто не предлагал? Если нет, то я буду первым
   H A D G E H O G s
 
124 - 09.05.21 - 15:36
SQL
Вставка - 50 секунд

SELECT top 1 *
  FROM [tmp].[dbo].[catalog_prices]
  where [ID]='2326434'
32 мс

CREATE UNIQUE INDEX Priceidx ON catalog_prices (id);
103 мс

SELECT *
  FROM [tmp].[dbo].[catalog_prices]
  where [ID]='2326434'

1 мс
   Djelf
 
125 - 09.05.21 - 15:53
(124) Те же яйца что в (119), только в профиль!
Выборка по индексу что так, что сяк будет 0-3 мс, и это не существенно.
Но есть и разница - на MSSQL придется что-то делать, а на SQLite нет!
Это небольшой профит, но он есть...
   trdm
 
126 - 09.05.21 - 17:35
(124) (125) Там в cvs все равно ненормализованная таблица.
Затяните в лоб - запросы на извлечение будут сложными.
Нужна предобработка.
   Djelf
 
127 - 09.05.21 - 20:27
(126) На таком объеме sqlite хорошо работает и без предобрабоки и без дедупликации.
Можно и это сделать, пару минут наверное займет (запрос уникальных значений у меня 5с занимает по любой колонке, ну +накладные, ну +несколько колонок, ну... за пару минут сработает)...
Но зачем? 300+ метров для sqlite не проблема, и в данном решении можно и без дедупликации обойтись
   Кирпич
 
128 - 09.05.21 - 20:49
У меня на ноуте на создание файлика с нужными данными уходит <4 сек и <50 мс на поиск нужной строки в этом файлике тупым перебором(это открытие файлика, поиск и закрытие). Нафиг тут sql серверы не нужны.
   evgpinsk_
 
129 - 09.05.21 - 22:36
(119) Пытался гуглить, но так и не понял, как этот код выполнять в 1с? (т.е. из csv быстро загнать данные в mysql)
либо что для меня лучше - из csv в dbf
если это делать средствами 1с через ADODB (построчно читать данные) - очень долго получается

п.с. ссылки на предыдущей странице на скрипт на гитхабе (csvTOdbf) - он у меня не отрабатывает мой конкретный CSV файл - на выходе dbf получается поломанным
   hogik
 
130 - 10.05.21 - 02:40
«для меня лучше - из csv в dbf»(с)

Самый быстрый способ:
1) Создать пустой DBF нужной структуры в среде 1С.
2) Вызвать программу на  FoxPro в которой удаляется CDX и выполняется APPEND FROM.
http://www.foxclub.ru/rhproject/project/html/c426861f-e5ef-44ae-96a6-8dbc7a4a2ad5.htm
3) Создать CDX в среде 1С.

Пример закачки файла для «Проверка по списку недействительных российских паспортов».  
http://xn--b1afk4ade4e.xn--b1ab2a0a.xn--b1aew.xn--p1ai/info-service.htm?sid=2000
 
 
   hogik
 
131 - 10.05.21 - 02:40
parameters p1
local p,t,s,f,r,k
set debug off
close all
on escape do figa
set sysmenu off
set safety off
set collate to "RUSSIAN"
set optimize off
t=chr(13)+chr(10)+"Для продолжения нажмите любую клавишу..."
f="list_of_expired_passports.csv"
r="Passport"
modify window screen title "Загрузка Серия+Номер" font "Courier",8 noclose
if vartype(p1)<>"C" then
    ? "Вызов: foxpass <Каталог>"
    wait t
    return 1
endif
p=alltrim(p1)
p=p+iif(right(p,1)="\","","\")
if file(p+f)=.F. then
    ? "Нет файла: "+p+f
    wait t
    return 1
endif
if file(p+r+".DBF")=.F. then
    ? "Нет файла: "+p+r+".DBF"
    wait t
    return 1
endif
if file(p+r+".CDX")=.T. then
    delete file (p+r+".CDX")
endif
s=seconds()
? "Обрабатывается:    "+p+f
use (p+r) exclusive
zap
append from (p+f) fields Code delimited with tab as 1251
k=reccount()
use
? "Загружено записей: "+alltrim(str(k,20,0))
? "Время выполнения:  "+alltrim(str((seconds()-s)/60,20,0))+" мин."
wait t
return 0
**********************************************************************
function figa
endfunc
**********************************************************************
   Garykom
 
132 - 10.05.21 - 02:48
(130) (131) приколист где для начала он foxpro возьмет с учетом лицензии?
   hogik
 
133 - 10.05.21 - 05:00
(132)
«приколист где для начала он foxpro возьмет с учетом лицензии?»(с)
Например, возьмёт runtime library для FoxPro и один EXE (исходный текст ниже) файл позволяющий выполнять исходные тексты.

parameters p0,p1,p2,p3,p4,p5,p6,p7,p8,p9
local f
if !empty(p0)
    f=upper(alltrim(p0))
    f=f+iif(right(f,4)==".PRG","",".PRG")
    if file(f)
        f=substr(f,1,len(f)-4)
        compile &f
        do case
            case empty(p1)
                do &f
            case empty(p2)
                do &f with p1
            case empty(p3)
                do &f with p1,p2
            case empty(p4)
                do &f with p1,p2,p3
            case empty(p5)
                do &f with p1,p2,p3,p4
            case empty(p6)
                do &f with p1,p2,p3,p4,p5
            case empty(p7)
                do &f with p1,p2,p3,p4,p5,p6
            case empty(p8)
                do &f with p1,p2,p3,p4,p5,p6,p7
            case empty(p9)
                do &f with p1,p2,p3,p4,p5,p6,p7,p8
            otherwise    
                do &f with p1,p2,p3,p4,p5,p6,p7,p8,p9
        endcase
    endif        
endif
   evgpinsk_
 
134 - 10.05.21 - 10:20
Подтягивать ещё foxpro не очень бы хотелось. У меня всё работает, dbf создаю через ADO читая xls
Есть два нюанса, которые не нравятся и которые не знаю как решить:
1) Сейчас руками сохраняю из CSV в XLSX (читать напрямую через ADO файл CSV не получается)
2) Время выполнения чтения первых 7ми столбцов xlsx файла - 250 секунд, что терпимо.
Но если ещё читать и остальные 170 столбцов - очень долго простым перебором
   trdm
 
135 - 10.05.21 - 10:58
(134) парси "в лоб". Без Excel. Ваще быстрее будет и не надо буде извращаться. И лишние инструменты отпадут и быстрее будет.
   evgpinsk_
 
136 - 10.05.21 - 11:25
(135) Возможно да, но опять много времени тратить на переделку не хочется ), когда уже есть почти работающий инструмент
   Garykom
 
137 - 10.05.21 - 12:23
(136) говно а не инструмент пока
а насчет "опять много времени тратить" еще раз повторю твоя задачка нормальным прогом решается за 2-3 часа
   Garykom
 
138 - 10.05.21 - 12:36
(137)+ так как у тебя 77 то значит винда
а значит читать через http://www.script-coding.com/WSH/FileSystemObject.html#3.24.
OpenTextFile или OpenAsTextStream
если CSV без лишних разделителей ("," или ";") внутри полей то далее простейше
и делай что хочешь, хочешь индекс делай в DBF а читай из CSV или все в DBF перегоняй
   evgpinsk_
 
139 - 10.05.21 - 12:41
(137) В чём конкретно говно ? )
Способ решения вполне нормальный выбран:
Через ADO читаем исходный файл с данными и закидываем его в DBF, далее по индексу поиск нужно товара в прайсе занимает милисекунды.

Проблемы две: время создания DBF файла через ADO 250 секунд если читать по минимуму только первые 8 столбцов (и критически долго - если все столбцы)
Приходится руками конвертировать из CSV в  XLSX

Решить эти две проблемы программисту занимает не 2-3 часа - а минут 5 :)
и в теории это мне известно, 
вараинт А) либо вместо dbf использовать SQLlite как в примере (119), но гугл не даёт мне конкретного примера какой ситнтакис
в самой 1с этого кода из (119):
DROP TABLE IF EXISTS vtPrice;
CREATE VIRTUAL TABLE vtPrice USING csvfile('d:\temp\price\catalog_prices_2021-05-08_13_05_50.csv',0,1);
ATTACH  'd:\temp\price\catalog_prices_2021-05-08_13_05_50.db3' as Price;

вариант Б) использовать сторонню софтину CSVtoDBF - но не смог найти через гугл чтото работающее: либо платное, либо кряки с вирусами.
   evgpinsk_
 
140 - 10.05.21 - 12:45
(138) Помню что полгода назад читал CSV файлы "в лоб"
и помню что тоже много нюансов вылазило, и количество строчек кода для лечения всех этих нюансов помню было точно не меньше 10-20.

Не хочется начинать пробовать чтобы опять упереться в какойто нюанс и сидеть над ним несколько часов.

Если не найду работаюший скрипт CSVtoDBF или не получу подсказку-пример как закинуть CSV  в SqLite (а это было бы полезно и для общего развития)
тогда уже буду думать по смене принятого алгоритма решения
   Djelf
 
141 - 10.05.21 - 12:48
(140) Да я же тебе все запросы в sqlite в (119) написал. Это все работает.
Или тебе все это в код на 1С нужно обернуть? Там же простые запросы по очереди, ничего сложного...
   evgpinsk_
 
142 - 10.05.21 - 12:49
(138) Проблема в том, что инструменты которые по этой ссылке для меня не знакомы. И если знающему эти инструменты их приминение занимает 1-2 минуты
то для меня сначала нужно будет потратить несколько часов на их изучение.

ну не программер я )
Трачу пару часов в неделю на решение каких то задач, т.к. мне это интересно. Но уровень знаний в большей степени только на уровне базового 1с
   evgpinsk_
 
143 - 10.05.21 - 12:50
(141) Сами запросы в (119) мне понятны. Но да, к сожалению мне не понятно как это закинуть в 1с.
Примеров гугл на даёт (
   evgpinsk_
 
144 - 10.05.21 - 12:54
И по ссылке (30) пример реализации "CSVtoDBF для больших массивов данных" в 1с тоже не доступен. Потратил час времени на поиск в гугле но зря
   mistеr
 
145 - 10.05.21 - 12:54
700К это фигня, если честно. Любая in-memory БД и будет летать при наличии памяти. SQLite тоже справится.

А "пределах нескольких секунд" справится даже справочник в основной базе. Ночью обновляешь, днем читаешь.

Иля я проблемы не понимаю.
   mistеr
 
146 - 10.05.21 - 12:55
Если проблема прочитать CSV и залить в справочник, то найма программиста, за 2-3 ч. сделает.
   mistеr
 
147 - 10.05.21 - 12:55
(146) *найми*
   evgpinsk_
 
148 - 10.05.21 - 12:57
(146) Понимаю что иногда читается между строк, но "прочитать CSV и залить в справочник" я и сам сделал.
Но штатное решение  занимает не один десяток минут на чтение всего CSV файла размером 267МЕГАбайт
   mistеr
 
149 - 10.05.21 - 12:59
(148) Странно, но допустим. Это проблема? Раз в сутки можно и 20 минут выделить на это.
   evgpinsk_
 
150 - 10.05.21 - 13:02
(149) Да, т.к. читать этот файл мне хотелось бы дважды в сутки и в рабочее время. Читается это в специальном сеансе Робота, где крутится 1с.
И если 1с зависает на 20-30 минут монопольно на чтение CSV файла, то в этом момент не работаю другие задачи (например чтения оналйн заявок с интернет-магазина)
   Djelf
 
151 - 10.05.21 - 13:10
(142) Тогда понятно...
Ну ладно, вот тебе код на 1С
Функция КонвертерCSV2Sqlite(ИмяФайлаCSV)

    ИмяФайлаSqlite = Лев(ИмяФайлаCSV,СтрДлина(ИмяФайлаCSV)-4)+".db3";

    База=СоздатьОбъект("SQLiteBase");

    База.Открыть(ИмяФайлаSqlite);
    База.РазрешитьЗагрузкуРасширений(1);

    Запрос=База.НовыйЗапрос();

    Запрос.ВыполнитьЗапрос("PRAGMA synchronous = OFF");    
    Запрос.ВыполнитьЗапрос("PRAGMA journal_mode = MEMORY");

    Запрос.ВыполнитьЗапрос("SELECT load_extension('sqlite3_mod_csv','sqlite3_extension_init');");
    Запрос.ВыполнитьЗапрос("DROP TABLE IF EXISTS vtPrice;;");
    Запрос.ВыполнитьЗапрос("CREATE VIRTUAL TABLE vtPrice USING csvfile('"+ИмяФайлаCSV+"',2,1);");

    НачВремя = _GetPerformanceCounter();
    Запрос.ВыполнитьЗапрос("DROP TABLE IF EXISTS Price");
    Запрос.ВыполнитьЗапрос("CREATE TABLE Price AS SELECT * FROM vtPrice");
    КонВремя = _GetPerformanceCounter();
    ВсегоЗаписей = Запрос.ВыполнитьЗапрос("SELECT count(*) FROM Price;",0);
    ЗаписейВСекунду = Окр(ВсегоЗаписей/(1+КонВремя-НачВремя)*1000);
    
    Сообщить("Импорт завершен за "+(КонВремя-НачВремя)+" мс, загружено "+ВсегоЗаписей+" записей, загрузка "+ЗаписейВСекунду+" записей/с");
    Запрос.ВыполнитьЗапрос("DROP TABLE IF EXISTS vtPrice");

КонецФункции


И код для консоли sqlite3.exe. Можешь в батник завернуть, как - ищи сам.

sqlite> .open target.db
sqlite> .load sqlite3_mod_csv.dll
sqlite> CREATE TABLE Price AS SELECT * FROM vtPrice;
sqlite> .timer on
sqlite> DROP TABLE IF EXISTS Price;
Run Time: real 0.473 user 0.140625 sys 0.328125
sqlite> CREATE TABLE Price AS SELECT * FROM vtPrice;
Run Time: real 48.485 user 41.171875 sys 4.734375
sqlite>


Без моего расширения файл, загрузить можно, но исходник в кодировке 1251, а sqlite работает в utf8, потребуется перекодирование, а у меня оно встроено.
   evgpinsk_
 
152 - 10.05.21 - 13:15
(151) Спс, изучаю
   Djelf
 
153 - 10.05.21 - 13:18
(152) А 1sqlite и sqlite3_mod_csv_03 забирай отсюда https://cloud.mail.ru/home/1sqlite/
   evgpinsk_
 
154 - 10.05.21 - 13:55
(153)  Может быть из-за старой версии 1sqlite?
База.РазрешитьЗагрузкуРасширений(1);
{Обработка.ЗагрузкаДанныхОнлайнера.Форма.Модуль(16)}: Поле агрегатного объекта не обнаружено (РазрешитьЗагрузкуРасширений)

п.с. по ссылки на маил.ру - нет файлика
   Djelf
 
155 - 10.05.21 - 14:58
(154) Конечно из-за старой, и очень-очень старой! В оригинальной версии Орефкова загрузка расширений была задумана, но не работает.
Вот правильная ссылка https://cloud.mail.ru/public/9znr/ZJ6ULE9aR
   Вафель
 
156 - 10.05.21 - 15:08
Мускул поднять. Он умеет балк лоад из цвс
   evgpinsk_
 
157 - 10.05.21 - 15:20
(155) Да, у меня была 1.0.2.3
Более свежая 1.0.2.6 решила проблему
   evgpinsk_
 
158 - 10.05.21 - 15:22
За 37 секунд загружается CSV размером 700Мб в Sqlite базу
Сейчас буду изучать как его читать )
   Djelf
 
159 - 10.05.21 - 15:43
(158) Это самое простое...
 Запрос.ВыполнитьЗапрос("CREATE UNIQUE INDEX [idxGoods] ON [Price]([ID товара]);");
 ТаблицаЗначений=Запрос.ВыполнитьЗапрос("SELECT * FROM Price WHERE [ID Товара]='12';");

Создаем уникальный индекс на код товара и запрос в ТЗ.
Тут есть заморочки с именами колонок!
Имя колонки из-за того что в нем пробелы - в квадратных скобках, а тип значения колонки [ID Товара] - строка, поэтому в одинарных кавычках.
   mistеr
 
160 - 10.05.21 - 15:53
(159) Поскольку ТС не совсем программист, нужно отдельно отметить, что индекс создается один раз после загрузки.


А параметры умеет это расширение?
 
 
   Djelf
 
161 - 10.05.21 - 15:57
(160) Таблица же дропается перед загрузкой, проблем не будет, но можно написать и так:
Запрос.ВыполнитьЗапрос("CREATE UNIQUE INDEX IF NOT EXISTS [idxGoods] ON [Price]([ID товара]);");
Какие-то параметры умеет https://infostart.ru/public/805029/ там написано что умеет.
   evgpinsk_
 
162 - 10.05.21 - 16:02
(160) Да, заметил ). Через Попытку Исключение
обрабатываю.

И ещё чисто теоретический вопрос ради интереса:
в самом CSV файле нет отдельного столбца, которое нужно индексировать для поиска.
индекс нужно строить по части поля столбца, который содержит путь к файлу:
http://catalog.onliner.by/cartridges/xerox_compat/0006r01179

и индексируемым значением для поиска будет текст за последним слешем: "0006r01179"

простой вариант решения - сделать предобработку CSV файла, выделив в нём это нужное значение части поля в отдельный столбец.
Вопрос- так и делать , либо движок sqlite может решить эту задачи своими средствами?
   mistеr
 
163 - 10.05.21 - 16:05
(161) Я имел в виду, что не при каждом поиске индекс создавать. :)
   mistеr
 
164 - 10.05.21 - 16:08
(162) Добавить колонку, сделать UPDATE SET <колонка> = <выделить нужную часть>
   evgpinsk_
 
165 - 10.05.21 - 16:11
(163) Так Djelf это понял и привёл пример как анализировать есть ли созданный индекс
(164) Вопрос как выделить нужную часть. Нужно взять всё то правее относительного последнего / в анализируемой строке.
sql язык умеет найти эту последнюю часть текста?
   Djelf
 
166 - 10.05.21 - 16:12
(163) Индекс же в файле хранится, т.е. в движке sqlite, а не в обвязке для 1C - 1sqlite/
(162) Может, движок sqlite поддерживает индексы на основе выражения, но я этот вариант не пробовал.
Может сработать, а может и нет. Выделение части из строки не очень простой вариант индекса. Лучше отдельный столбец и в него что-то нужно запихнуть.
Либо, не парится, а искать по like, это вероятно не будет слишком медленно...
   evgpinsk_
 
167 - 10.05.21 - 16:17
в теории like может выдать лишние варианты поиска.
Значит буду делать предобработку CSV
   mistеr
 
168 - 10.05.21 - 16:30
(165) Нет, последнюю не получится, только первую. Лучше при загрузке выделить.
   Djelf
 
169 - 10.05.21 - 16:30
(167) У тебя семь пятниц на неделе, сначала ты пишешь "В прайсе есть столбец "IDтовара" по которому будет осуществляться поиск."
Теперь у тебя "индекс нужно строить по части поля столбца, который содержит путь к файлу:"
Нельзя настолько менять условия задачи по ходу дела!

Интересно сколько времени у тебя займет предобработка твоего 700метрового csv...
Видимо задача стоит не ускорять загрузку файла, а наоборот - замедлять! ;)
   Djelf
 
170 - 10.05.21 - 16:35
(168) Это в больших базах sql не очень сложно, можно и в sqlite например так: https://github.com/mayflower/sqlite-reverse-string
Т.е. реверсируем строку, ищем разделитель, вычитаем, дополняем, выкусываем. Бинго!
Либо пишем свой велосипед...
P.S. давно уже перестал удивляться почему поиск "с начала" везде сделан, а "поиск с конца" почти нигде.
   mistеr
 
171 - 10.05.21 - 16:38
(170) Либо просто загружаем нормальные данные :)
   Djelf
 
172 - 10.05.21 - 16:39
И!!! (162) Код товара в файле уникален. А вот код "0cb435a" в строке "http://catalog.onliner.by/cartridges/hp_compat/0cb435a" уникален?
Точно-точно уверен? Ты генерацию этого кода у onliner.by смотрел? В техподдержку писал? Они точно гарантируют уникальность?
   evgpinsk_
 
173 - 10.05.21 - 16:47
(169) Ну изначально я ведь не знал каким будет итоговое решение )
Поэтому и выразился фигурально про ID товара 

Да, уже понимаю, что предобработка тоже время кушать будет, если в лоб решать )

(172) Да, эта часть поля тоже будет уникальным индексом.

Я в DBF файл выгружал и по нему строился индекс. И мой весь движок работы с онлайнером построенном именно на этом индексе (последняя часть html строки товара)
а IDтовара есть только в этом CSV файле и парсить в других местах я его не могу.
   Arbuz
 
174 - 10.05.21 - 17:07
(170) Ух ты ж! Жемчужина в навозе... А есть собранное? Там же что-то с кодировками в 1C и sqlite?
   Djelf
 
175 - 10.05.21 - 17:54
(174) Маловато что-то жемчужин в этом * завалялось, подсыпем еще чуток...
 Запрос.ВыполнитьЗапрос("ALTER TABLE Price ADD COLUMN СуперКлюч;");
 Запрос.ВыполнитьЗапрос("UPDATE Price SET СуперКлюч = replace([Ссылка на товар], rtrim([Ссылка на товар], replace([Ссылка на товар], '/', '')), '');");
 Запрос.ВыполнитьЗапрос("CREATE UNIQUE INDEX [idxСуперКлюч] ON [Price]([СуперКлюч]);");
 тз=Запрос.ВыполнитьЗапрос("SELECT * FROM Price WHERE СуперКлюч = '006r01177'");

   evgpinsk_
 
176 - 10.05.21 - 19:37
(175) Это круто.
Но не пойму что за функция Rtrim (par1,par2,par3,par4)  ?

Классически она отсекает пробелы справа в передаваемом параметре и у неё один параметр
   evgpinsk_
 
177 - 10.05.21 - 19:50
(176) Ошибся, правильно так:
Rtrim (par1,par2)
но всё равно не понятно
   Djelf
 
178 - 10.05.21 - 20:08
(177) Это магия sql! rtrim не так работает...

Выбери "раз": http://catalog.onliner.by/cartridges/xerox_compat/0006r01046
Убери разделители, это "два": http:catalog.onliner.bycartridgesxerox_compat0006r01046
Откуси справа от того что было в "раз", тем что получилось в "два" сверяя посимвольно справа, это "три": http://catalog.onliner.by/cartridges/xerox_compat/
Замени то что было в "раз" тем что получилось в "три" и получи конфетку: 0006r01046
[1c]

Кстати, замени
[1c]
Запрос.ВыполнитьЗапрос("CREATE VIRTUAL TABLE vtPrice USING csvfile('"+ИмяФайлаCSV+"',2,1);");
на
Запрос.ВыполнитьЗапрос("CREATE VIRTUAL TABLE vtPrice USING csvfile('"+ИмяФайлаCSV+"',2,1,'','');");

у меня там косячёк нашелся, без указания этих двух пустых параметров, значения в колонках кое-где съезжают ;(
   evgpinsk_
 
179 - 10.05.21 - 20:53
(178) "у меня там косячёк нашелся, без указания этих двух пустых параметров, значения в колонках кое-где съезжают ;("

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

Сейчас буду пробовать решить через замену в числовых столбцах запятой на точку
   Djelf
 
180 - 10.05.21 - 21:11
(179) Ладно, тогда SpecialEdition с отключенной запятой для разделителя: https://cloud.mail.ru/public/yvfM/hHZQEV13a
   evgpinsk_
 
181 - 10.05.21 - 21:17
(180) Работает )
Параллельно загуглил как через PowerShell производить автозамену в текстовых файлах
   Djelf
 
182 - 10.05.21 - 21:38
(180) Этот модуль отсюда взят http://www.ch-werner.de/sqliteodbc/
Я там много всякого наковырял, видимо не тестировал с разделителем запятая, либо не попадались такие файлы...
Давно дело было. Оригинальный и вылетал постоянно и тоже что-то с параметрами чудил не понятно. Мой хотя бы не вылетает ;)
Формат csv не сильно стандартизированный - слишком много опций нужно учесть чтобы прочесть ВСЕ возможные варианты.
   andrewalexk
 
183 - 11.05.21 - 10:12
:)
можно еще проще - без создания избыточных сущностей в сикульной или файловой базе
через команду dos
findstr /I /g:
в текстовый файл
   Garykom
 
184 - 11.05.21 - 10:23
я конечно все понимаю но тут вышло не программирование а какое то шамано-эникейство из разрядо дендрофекальных
причем технологии/инструменты вроде и ничего но применяют их через одно место, вместо нормального программирования
   Djelf
 
185 - 11.05.21 - 10:30
(184) А что не так?
Чем отличается подключение расширения к sqlite от подключения расширения к 1С 8.3?
И чем отличается подключение внешней таблицы от подключения внешних источников данных к 1С 8.3?
Те же яйца, только в профиль...
   Garykom
 
186 - 11.05.21 - 10:39
(185) Не люблю когда на конкретную технологию/софт затачиваются без крайней необходимости не для разовой задачи
Лучше все что можно делать своим кодом, чтобы при необходимости легко с dbf на sqlite или mssql или даже posgtresql перейти
   Garykom
 
187 - 11.05.21 - 10:43
(186)+ В случае ТС раз у него 77 то смотря файловая или sql надо это и юзать
Т.е. отдельно модуль чтения CSV, отдельно загоняние в DBF (тут для файловой можно хак, создать в 1С 7.7 табличку и ее заполнять внешним а искать/читать уже из базы) или в MSSQL (для SQL версии аналогичный хак можно)
По сути все встроенное и никаких левых лишних инструментов
   Garykom
 
188 - 11.05.21 - 10:44
(187)+ Справочник в 1С 7.7 создаем под данные, заполняем его снаружи (как таблицу DBF или MSSQL) а юзаем внутри 1С
   Djelf
 
189 - 11.05.21 - 11:00
(186) Ты про sqlite3_mod_csv? Ну, да, увы. Сколько не смотрел реализаций этой виртуальной таблицы для sqlite - все они кривые, а из 1251 вообще не умеют импортировать.
В этом модуле, я заново глянул, параметры разделителя были заявлены, но не реализованы.
Можно на Goland слепить аналогично расширение для sqlite - код будет значительно проще, чем на си.
(187) Чем хаки лучше ВК к 1С?

И... в этом файле же 176 колонок! Он целиком в dbf не помещается!
Т.е. нужен не один, а штук 5 справочников...
А дебупликация будет довольно затратной.
Даже на sqlite дедупликация названий магазинов пару минут занимает, а уж на языке 1С - вечность.

Ну а так, да булк-инсерт в mssql и все.
Но и тут тот-же самый булк-инсерт, только в sqlite!
А механизм расширений к sqlite это не хак, это стандартный и часто используемый механизм sqlite...
   evgpinsk_
 
190 - 11.05.21 - 13:06
(184) Можно чуть более конкретней, как именно читать из CSV в dbf или справочник 1с 200МБ текста за пару минут?
Я вроде как и спрашивал про это в (0), т.к. не знал
   Djelf
 
191 - 11.05.21 - 13:08
+(189) Специально для любителей Golang. Бинарник и исходники: https://cloud.mail.ru/public/r1Mi/gC37i35yg
А также для сторонников оборачивать все в скрипты...


Оригинальный проект здесь: https://github.com/wiremoons/csv2sql

Все немногочисленные изменения в diff.txt
+ загрузка из кодировки windows-1251
+ замена разделителя на точку с запятой
+ замена двойной кавычки экранирования на одинарную, используемую в sqlite
+ экранирование одинарной кавычки внутри поля

csv2sql.exe -f catalog_prices_2021-05-08_13_05_50.csv -t price
14c
sqlite3.exe prices.db3 ".read SQL-catalog_prices_2021-05-08_13_05_50.sql"
63c

   evgpinsk_
 
192 - 11.05.21 - 13:12
А  Djelf-у отдельный большой респект, даже не столько в помощи по конкретной задаче, сколько в раскрытии самих технологий. Для меня и думаю для многих именно это самое важное.
   Garykom
 
193 - 11.05.21 - 13:28
(190) файлик делится на несколько в несколько потоков (по числу ядер проца) пишется
   Garykom
 
194 - 11.05.21 - 13:30
(191) У тебя учетки что ли нет на гитхабе? Заведи, форкни и свои изменения туда
   evgpinsk_
 
195 - 11.05.21 - 13:35
(193) И это не будет "шамано-эникейство" ? ))
Если делать штаными средствами в лоб, то вместо 30 минут потратим 20 ? )
   Garykom
 
196 - 11.05.21 - 13:36
(195) Это не шаманство в отличие от разных извратов с екселями и прочими а обычное программирование
Фоновые задания даже в 1С есть в 8.3 и многопоточность используют очень часто
И не 20 минут а в лучших случаях можно за пару минут
   evgpinsk_
 
197 - 11.05.21 - 13:46
(196) В данной теме итоговое решение - не имеет отношения к екселю а использует импорт данных из исходного CSV в 1sqlite.
Напомню что исходный CSV файл - это 230Мб текста, около 700тыс строк и динамические столбцы с ценами магазинов на товары.
Просто импорт первых 7ми столбцов в лоб занимает несколько минут, что терпимо, если же также в лоб читать и обрабатывать все остальные 170 столбцов - время критически растёт.
И делить файл на части - это и есть костыльное решение проблемы. Всё равно оно будет больше 10минут.
Во всей этой теме я увидел конкретный дельный совет, (который смог понять) только от  Djelf.
Возможно тут были и другие решения, но я как-то их не заметил
   Garykom
 
198 - 11.05.21 - 13:53
(197) просто у кого то "Смотрю в книгу — вижу фигу" ))

а бесплатно за другого (он же зп получает наверно да?) готовый код кодить мне влом, писал только советы как можно
   RomanYS
 
199 - 11.05.21 - 13:55
(196) Разве у ТСа ни клюшки? В 8.3 и стандартных средств будет достаточно чтобы быстро прочитать текстовый файл и найти нужную строку
   pechkin
 
200 - 11.05.21 - 13:56
(199) вопрос в скорости
  1  2  3  4   

Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.