• Очень быстро лить в БД 1 млн. строк в секунду и настолько же быстро читать их. Как лучше осуществить?

    @rPman
    лить в таблицу (ticker, price, quantity, oper) ежесекундно ~1 млн. строк
    колись, у какого брокера и за какие деньги ты получаешь эти данные такого объема?

    Есть данные типа level2/3 (когда вместе с событиями trade тебе льют depth update, изменения в стакане или сами события в стакане, это данные дорогие, доступ на большом рынке тебе дадут только с машины в датацентре брокера, где надо платить еще и дорогую аренду сервера. В мире криптовалют эти данные пока бесплатны, к примеру один binance (крупнейший поставщик биржевых событий, сравним с ними coinbase точнее gdax остальные в сумме наверное от силы столько же дадут) и тот дает порядка 4 тысяч событий в секунду, максимум что я от них видел.

    По теме вопроса, всегда, в первую очередь нужно задавать вопрос не как и где хранить данные а как ты их будешь читать. Судя по теме с высокой вероятностью тебе не нужены отдельные случайные события, а нужны данные блоками, на интервале, поэтому и в базе хранить данные лучше этим блоками (вот тут уже надо считать, проводить бенчи на основе твоих данных и твоих мощностей), скорее всего тебе хватит почасовые массивы, тогда при любом запросе потока на момент времени x-y тебе нужно читать минимум две записи, это сотни миллисекунд, плюс фильтрация, на эту уходят десятки миллисекунд даже на php, если в базе данные удобно сериализованы, дольше передавать и обрабатывать будешь.

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

    Так вот, хранить данные можно буквально в файлах, файловая система - отличная key value база данных (дели по файлам и каталогам на основе валютной пары, биржи, и временного интервала, но на время лучше индекс заводить), работать с такой базой неудобно только при обслуживании (backup/restore) но если изначально организовать хранилище в отдельном разделе, то и работать с ним напрямую.

    Одно время я хранил данные в gzip json, но недавно открыл для себя igbinary, чудесная вещь, бинарный при этом тоже пакуется, файлы храни на btrfs со включенным сжатием zstd ultra.
    Ответ написан
    6 комментариев
  • Очень быстро лить в БД 1 млн. строк в секунду и настолько же быстро читать их. Как лучше осуществить?

    @Yury093
    Конечно может, вопрос в железе. И микроскопом можно забить гвоздь.
    Но на слова "хочу быстро вставлять и быстро читать потоком" так и хочется ответить "а зачем тебе БД?"

    Поэтому хотелось бы уточнить у автора: а вот кроме описанного "вставить миллион, считать миллион" - что предполагается делать с данными? Менять их построчно? Искать по какому-то ключу? это все надо? Если нет - я бы все же рекомендовал не использовать БД.

    Тут следует понимать что любая нормальная БД это [почти] всегда двойная запись на диск: вы пишите в таблицу И в лог базы данных. Именно поэтому файл или Kafka или иной MQ будет всегда быстрее.

    Ну а если БД все равно нужно - ну тогда BULK режимы вам в помощь. Обычно они используются для пакетной инициализирующей загрузки. В некоторых БД они на время своей работы могут отключать какие-то фичи или даже логирование в лог транзакций.
    ----------------------------
    Вообще по всем признакам в вашем случае идеальным будет вариант писать в MQ (RabbitMQ или Kafka или см аналоги), а уже из нее в БД. "Все так делают", по крайней мере в крупных компаниях это довольно типовое решение для подобных вашей задач. Причем БД в этой истории нужна только если вам потом нужно хранить и селектить. Если после первой операции данные вам более не нужны, либо нужен только бэкап, то БД не нужна - пишите в файл, пакуйте в zip (в энтерпрайзе - кидайте файлы в Hadoop в каком нибудь Parquet формате).
    Ответ написан
    1 комментарий
  • Экспорт данных из QUIK по ODBC. Как налету преобразовывать VARCHAR-поля в правильные (DATE, DECIMAL, ENUM)?

    @Akina
    Сетевой и системный админ, SQL-программист.
    В тексте запроса ЛЮБЫЕ данные представлены как их строковые представления. Да что там - сам SQL-запрос есть строковый литерал.

    Поэтому следует озаботиться исключительно правильным представлением. Форматом. Если данные - число, то десятичным разделителем должна быть точка. Если это дата или строка - должны присутствовать обрамляющие кавычки, причём дата должна быть в формате, понятном текущей СУБД (предпочтительно YYYY-MM-DD - этот формат понимают все СУБД), а в строке должны быть экранированы все символы, являющиеся служебными. И т.п.

    Если выгруженные данные не соответствуют этому формату, то в запросе на добавление можно использовать не напрямую значение (и потом маяться дурью в процедуре/триггере), а, используя встроенные функции, преобразовать данные к правильному типу. Например, если в поле надо вставить число, а в выгрузке использована запятая в качестве разделителя, это будет
    INSERT ... VALUES ( ... , CAST(REPLACE(@value, ',', '.') AS DOUBLE), ...
    Ответ написан
    Комментировать
  • Почему в MySQL8 тип DECIMAL неупакованный?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Во-первых, упаковка там несколько другая. Каждые полная девятка цифр занимает четыре байта, неполная меньше (есть таблица). Целая и дробная части упаковываются отдельно. Ваш формат 13,6 должен занимать 7 байт.
    https://dev.mysql.com/doc/refman/8.0/en/precision-...

    Во-вторых, функция LENGTH принимает на вход строку, так что значение DECIMAL приводится к строке, отсюда и 14 символов.
    https://dev.mysql.com/doc/refman/8.0/en/string-fun...
    Ответ написан
    4 комментария
  • Экспорт данных из QUIK по ODBC. Как налету преобразовывать VARCHAR-поля в правильные (DATE, DECIMAL, ENUM)?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Подход абсолютно неграмотный. MySQL при вставке в таблицу (как и при большинстве операций) автоматически приводит данные к нужному типу.
    А поля DATA и ENUM вообще всегда передаются как строки, только DATA должно быть в правильном формате, 'YYYY-MM-DD'.
    Ответ написан
    6 комментариев
  • Какой выбрать способ для работы с QUIK в приложении на Python?

    @DonStron
    В случае с ODBC интересует, можно ли как-то автоматизировать процесс присоединения через ODBC к базе данных или же каждый раз нужно выбирать таблицу, нажимать ПКМ и т.д.?

    С галочкой "Вывод после создания", которая ставится в настройках вывода по ODBC в таблице - Квик сам начинает пихать данные в базу сразу после запуска Квика. Т.е. настроил один раз и забыл, оно работает и стартует само.
    Если не нужен автостарт экспорта в базу, то есть галочка для вывода по требованию: "Вывод при нажатии Ctrl+Shift+O". Просто делаешь активным окно Квика - нажимаешь сочетание клавишь и данные пошли.

    Тоже самое есть и у вывода по DDE (старт после запуска), правда чтобы корректно работало, сервер DDE должен быть запущен до запуска Квика. Запуск по сочетанию клавиш тоже есть.
    Для минимальной задержки вывода оп DDE в инфофайле квика делают вот такую настройку:
    5bf51d0c04ae5834341910.png

    Ещё можно рассмотреть вариант "всё в одном" без квика вообще - это SmartCom у брокера АйТи Инвест. Модуль Питона для подключения есть на гитхабе, но не знаю допилен ли он энтузиастами до конца. Моих навыков в Питоне пока не хватает. Правда смартком с абоненткой ежемесячной, если торговой комиссии набегает меньше, чем стоимость абонентки.

    У меня сейчас работает так:
    Данные для своих хитрых графиков получаю из Квика по ODBC, питон их обрабатывает и показывает.
    Установку базы и настройку вывода делал по этой инструкции. Ставил старые версии, чтобы не разбираться, а то в комментах там жаловались, что настройки в новых изменились.
    Для ручной торговли подключен к Квику привод Кускальп по DDE, там руками выставляю приказы.

    Когда обкатаю идею и подниму навыки питона, то попробую со всем этим переехать на смартком. А может даже перепишу всё под C#, он стыкуется со смартком без проблем, всё готово. Правда для этого придется изучить C#
    Ответ написан
    1 комментарий
  • Почему не экранируется символ одинарной кавычки?

    vollossy
    @vollossy
    Веб-разработчик с небольшим опытом работы
    Потому что то, что вы видите, это не строковое представление для строки(простите за тавтологию), а ее "техническое" представление. Попробуйте сделать
    >>> print('"Isn\'t," they said.')
    Дело в том, что каждый объект в python может иметь 2 метода: __repr__ и __str__. Первый отвечает за "техническое" представление, которое помогает однозначно идентифицировать объект и используется для отладки и в том числе в REPL, а второй за строковое представление, удобное для чтения человеком. Например, в случае с datetime.date(2021, 6, 1), __repr__ вернет 'datetime.date(2021, 6, 1)', а __str__: '2021-06-01'.

    UPD: увидел обсуждение в комментариях касательно ' и "
    > Почему в вышеуказанном примере бэкслэш выводится, в примере ниже - нет?
    >>> "\"Yes,\" they said."
    '"Yes," they said.'

    Тут штука в том, что двойные кавычки это что-то вроде синтаксического сахара, который позволяет нам вставлять всякие непечатаемые символы, а также использовать переменные(как f-строки или r-строки). В итоге их отображение все равно приводит их к виду одинарных кавычек с соответствующим форматированием. Для одинарных кавычек обратный слеш при работе с двойными не нужен, поэтому он и не отображается.
    Ответ написан
    2 комментария
  • Как наложить два списка?

    @Drill
    d3 = [i2 for i1,i2 in zip(d1,d2) if i1]
    Ответ написан
    Комментировать
  • Как наложить два списка?

    phaggi
    @phaggi Куратор тега Python
    лужу, паяю, ЭВМы починяю
    d1 = [1, 0, 1, 0]
    d2 = ['qwe', 'asd', 'zxc', 'wer']
    print([d2[i] for i, _ in enumerate(d2) if d1[i]])
    Ответ написан
    2 комментария
  • Как наложить два списка?

    aRegius
    @aRegius
    Python Enthusiast
    itertools.compress

    d3 = list(compress(d2, d1))
    Ответ написан
    Комментировать
  • Как наложить два списка?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    d1 = [1, 0, 1, 0]
    d2 = ['qwe', 'asd', 'zxc', 'wer']
    
    d3 = [x[1] for x in filter(lambda x:x[0] == 1, zip(d1, d2))]
    
    print (d3)


    Ещё короче:

    d3 = [d2[i] for i in range(0,len(d1)) if d1[i] == 1]
    Ответ написан
    4 комментария
  • Какая ошибка в коде?

    @dmshar
    А причем тут неправильный код, когда у вас неправильная формула? Формула (и соответствующие код) для расчета сложных процентов выглядит следующим образом:

    base=100
    interest=0.1
    years=1
    repayment=base*(1+interest)**years
    print(repayment)


    Ну, или если очень хочется в виде функции, тогда так:
    def deposite(base,years,interest=0.1):
        return base*(1+interest)**years
    
    print(deposite(100,1)


    И никаких циклов тут не нужно.
    Ответ написан
    Комментировать
  • Можно ли сделать клон базового окружения в Anaconda Navigator?

    phaggi
    @phaggi Куратор тега Python
    лужу, паяю, ЭВМы починяю
    Вроде как рекомендуют вот так через консольку делать:
    conda create --name <env_name> --clone base
    Сам не пробовал.
    Ответ написан
    Комментировать
  • Как в Pandas определить "хитрую" оконную функцию?

    adugin
    @adugin Куратор тега Python
    У тебя на рисунке в одной строке ошибка
    df['new_column'] = df.groupby(['phonenumber', 'event']).cumcount(ascending=False)

    5ffb6518d4bed341141330.png
    Ответ написан
    5 комментариев
  • Как подсчитать кол-во строк в каждой группе при группирове по двум столбцам?

    adugin
    @adugin Куратор тега Python
    df.groupby(['client_id', 'phone_number']).count().reset_index()
    Ответ написан
    Комментировать
  • Как в DataFrame задать нужное имя вычисляемой колонки count()?

    adugin
    @adugin Куратор тега Python
    Посчитать количество уникальных client_id проще так:
    df.client_id.value_counts()
    df.client_id.value_counts().to_frame(name='count')


    Способов решить вашу задачу много. Например, можно просто переименовать индекс:
    new_df.index.name = 'my_index'

    Или задать имена колонкам:
    new_df.columns = ['count']
    Ответ написан
    Комментировать
  • Как в Oracle или Teradata разбить все строки таблицы на N равновеликие СЛУЧАЙНЫЕ выборки?

    select t1. *, ntile(N) over (order by dbms_random.random) nbatch  from t1

    А дальше выбираете нужные части nbatch.
    ntile в Oracle используется для построения гистограмм, поэтому +/- должен работать быстро.
    Ответ написан
    Комментировать
  • Почему send_keys в Selenium работает через раз?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Если спрашиваете совета как решить проблему, приводите воспроизводимые примеры.
    Мало того. что код не проверяете на опечатки, так еще и проблема у вас какая-то локальная. Может быть комп тормозит, может быть страница в браузере, может быть js на ней тупо рандомные нажатия клавиш пропускает.
    С учетом невоспроизводимости вашей проблемы, разумно было бы хотя бы попробовать дугие драйверы, хром тот же... А-то складывается впечатление, что "ой что-то не работает памагити!!!111"
    Ответ написан
    Комментировать
  • Почему send_keys в Selenium работает через раз?

    dimonchik2013
    @dimonchik2013
    non progredi est regredi
    ни с чем
    уж что-что, а print Питон и Селениум выводят на отлично

    а вот что там за JS у тебя в браузере - это надо посмотреть, вполне может не уметь обрабатывать быстро входящие символы

    итог: посылай кеи с задержкой в полсекунды
    Ответ написан
    2 комментария