Как стать автором
Обновить

Комментарии 13

Можно, но зачем?
Для хранения numpy массивов куда лучше подходит HDF.
Если Вы прочитали изображение с помощью cv2.imread из библиотеки OpenCV, например, то принцип остается тем же — ведь это, по сути, многомерный массив

По сути — это набор байтов. Который можно сохранить в блоб и без numpy. Я понимаю что это пример, пусть и неудачный.

Однако, советовать использовать pickle — плохой тон. Есть статья (правда, 2014 года), которая объясняет пару причин, но я также добавлю что протокол Pickle имеет тенденцию меняться и могут возникнуть сложности при смене версии Python. Совсем недавно была версия 3, сейчас уже 4, а может уже и 5.

Если вы используете numpy, то не совсем понятно почему вы не используете, например, метод tobytes() — по крайней мере это роднее для numpy.

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

И не буду рассказывать что случится когда в проект, написанный на, скажем, Python приходит новый язык (Java? C? JS?) и спрашивает — «а что такое pickle и как мне прочитать это поле из базы».
Ну так тоже можно далеко зайти — по сути, все является набором байтов) Метод tobytes() — один из вариантов. Но почему бы и нет? Разве вариант через pickle таит какие-то серьезные недостатки?

Что касается блобов — а как бы Вы организовали хранение структур именно в том виде, как они должны быть сохранены? Например, тензор высокой размерности? Причем без потери формы. Кстати говоря, а frombuffer() разве не плоский массив возвращает?

Что касается других языков — полностью согласен. В данном случае просто такая ситуация не рассматривалась (в конкретном проекте).
Но почему бы и нет?

Вы комментарий мой вообще читали? Он, в основном, посвящен ответу именно на этот вопрос.

Еще раз объясню: pickle — это небезопасный, не очень производительный и привязанный к одной конкретной версии одного конкретного языка (Python) протокол. Он сделан больше для внутреннего обмена структурами — подойдет максимум для обмена между форкнутыми процессами.

Хранить блобы в базе: а для чего? Реляционная БД предполагает более-менее долгосрочное хранение объектов с оптимизацией доступа (индексы, например). Если вам нужно хранить бинарные объекты — храните их в любом другом месте — как файлы, как записи в, например, Redis. Да, в базе можно, но мне каждый раз жалко базу когда я вижу такое.

Не надо так делать. Используйте подходящие scientific friendly форматы, например, HDF или Zarr. В базе можно хранить пути к этим файлам.


Более того, завязываясь на pickle вы делаете не language agnostic решение, что очень недальновидно.

Как написал чуть выше, да, с точки зрения других языков это непрактично. Но в конкретном проекте это было допустимо. Вариант же с хранением вне базы не очень подходил, т.к. просто объем информации очень велик и это не особо удобно (опять же, в данном конкретном случае).

Тут, например, действительно рекомендуют хранить в базе бинарные блобы как самое надежное решение:
https://dba.stackexchange.com/questions/2445/should-binary-files-be-stored-in-the-database


Но я всё же считаю, что для хранения очень больших объемов данных, особенно многомерных массивов, лучше всего подходит именно HDF5. Этот формат был специально разработан для таких случаев.


pickle в любом случае лучше не использовать. Сегодня вы используете только python, а завтра вам нужно работать с вашими данными из другого языка. И тут как раз использоваие универсального формата данных, не завязанного ни на Python, ни на NumPy будет лучшим решением.


Если вам не нужны возможности реляционной базы, а нужно именно хранилище для многомерных массивов, посмотрите в сторону HDF5 или Zarr, возможно, это как раз то, что нужно.

Спасибо! В данном случае там на этой базе завязан проект, так что остановимся на бинарниках, а вот уже в следующие разы, если будет потребность хранения именно такого рода данных отдельно, будем смотреть в сторону HDF5. Теперь люди смогут зайти на эту страницу и прочитать вообще все основные варианты: и pickle, и HDF5, и tobytes. Можно сводную заметку сделать по этому поводу))

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

Простите, но даже по этой ссылке достаточно много очень аргументированных ответов почему хранить в базе — плохо.

Единственный ответ, который я могу принять на эту тему — «лень заморачиваться, по-быстрому на коленке приделаю, пофиг на все минусы», но статью об этом я писать бы не стал.
HDF5 не во всем уж и идеальный формат: при чтении некорректное завершение программы может сломать весь файл, быстро не посмотреть метаданные без спец ПО, только одна реализация. Также отсутствуют публичные issue. Кроме того, сборка со стороны c++ и cmake не сильно радует стабильностью.
Использование pickle — допустимо. Хранение блобов в базе — допустимо. В конкретном проекте. Я сам использовал и то и другое.

Даже комментарии в коде на русском языке можно писать в проекте, который кроме вас и вашего кота никто не видит (я не использовал).

Но когда вы пишете об этом статью — готовьтесь принять критику и замечания о best practices. Тем более что «данный конкретный случай» вы не объяснили и оставили нам возможность показать себя умными, критикуя ваш подход.

Без проблем — критика всегда полезна. Зато все аккумулировано в одном месте и поиски многих русскоязычных новичков теперь займут в разы меньше времени) Вижу это одной из главных задач подобных постов)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории