Хранение бинарных объектов
RethinkDB поддерживает собственный тип бинарного объекта, позволяющий использовать ReQL для непосредственного хранения бинарных объектов в базе данных. Драйвер ReQL прозрачно переводит между типом ReQL и типами bytes (в Python 3) или str (в Python 2).
Примечание: Тип бинарного объекта предназначен для данных, которые нельзя надёжно сохранить как строки UTF-8, например, загруженные файлы. Если вы работаете с данными, которые можно сохранить как строки, обычно проще использовать тип данных строки.
В этих примерах будем предполагать, что подключение к RethinkDB доступно в глобальной области видимости как conn.
Хранение загруженных файлов в базе данных
Для веб-приложений часто требуется принимать загрузки файлов от пользователей; с RethinkDB вы можете хранить эти файлы непосредственно в базе данных.
def save_file(file_path, save_name, user_id):
"""
Store the file at 'file_path' with the filename 'save_name'.
"""
fh = open(file_path, 'rb')
contents = fh.read()
fh.close()
r.table('files').insert({
'user_id': user_id,
'filename': save_name,
'file': r.binary(contents)
}).run(conn)
В save_file, мы передаём путь к загруженному файлу (который может находиться в временной папке хранения, даже с временным именем, в зависимости от используемой библиотеки загрузки), имя для сохранения файла и идентификатор пользователя, который загрузил файл. Команда ReQL binary используется для хранения содержимого файла как бинарного объекта в поле file.
def get_user_file_ids(user_id):
"""
Retrieve the IDs of previously-saved files for a user as a list of
dicts: [{'id': x, 'filename': y}, ...]
"""
return r.table('files').filter({'user_id': user_id}).pluck(
'id', 'filename').run(conn)
def get_file(file_id):
"""
Retrieve a file by its ID. Returns a dict with 'filename' and 'file'
keys.
"""
return r.table('files').get(file_id).pluck('file', 'filename').run(conn)
Затем есть две функции для извлечения файлов: одна для получения списка загруженных файлов пользователя (get_user_file_ids) и одна для получения самого файла (get_file). Нам не нужно использовать binary снова здесь; драйвер ReQL вернёт правильный тип данных для поля file в нашем объекте.
Хранение аватаров пользователей
Вот ещё один, более интересный пример: добавление аватаров Gravatar к учётным записям пользователей. Мы можем использовать http для их получения.
import hashlib
def add_gravatar(user_id):
"""
Add a gravatar field with the binary avatar icon to user accounts if they
have an avatar associated with their email address.
"""
email = r.table('users').get(user_id)['email'].run(conn)
hash = hashlib.md5(email).hexdigest()
gravatar_url = 'http://www.gravatar.com/avatar/' + hash + '?d=retro'
r.table('users').get(user_id).update({
'gravatar': r.http(gravatar_url, result_format='binary')}).run(conn)
Где же r.binary? Вам это не нужно в данном случае, потому что r.http вернёт бинарный объект с параметром result_format='binary'. (Если тип MIME на сервере-отправителе установлен правильно, вы можете даже убрать этот параметр, и r.http определит правильный тип.)
© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/docs/storing-binary/python/