Если вы готовы сделать это в Python, вот пример, который должен работать:
import boto
import gzip
import psycopg2
import tempfile
# database connection setup
connection = psycopg2.connect('postgresql://scott:tiger@localhost/mydatabase')
connection.autocommit = True
cursor = connection.cursor()
# aws connection setup
s3_connection = boto.connect_s3('<aws access key>', '<aws secret key>')
bucket = s3_connection.get_bucket('<bucket>')
with tempfile.NamedTemporaryFile() as t:
with gzip.GzipFile(t.name, mode='wb') as g:
cursor.copy_expert("COPY ({0}) TO STDOUT WITH CSV HEADER".format('<select_query>'), g)
key = boto.s3.key.Key(bucket, '<s3_key>')
key.set_contents_from_filename(g.name)
В этом процессе используется модуль tempfile
в Python, который позволяет вам создать файлто, что получает, используется, а затем удаляется в процессе.Диспетчер контекста (with tempfile...
) упрощает управление процессом записи файла, поэтому вам не нужно удалять его вручную.В зависимости от того, как вы настроили временный файл, вы можете сделать файл доступным или никогда невидимым для системных пользователей.По сути, вы передаете оператор SELECT в STDOUT, а затем записываете STDOUT в временный файл.Вы по-прежнему обязаны использовать в своей базе данных оператор SELECT с точки зрения управления памятью, скорости и доступа.
Преимущество заключается в том, что вам не нужно сохранять весь файл в памяти при попытке передать его вS3;Недостатки в том, что вам нужно достаточно дискового пространства для временного хранения файла, и что он явно медленнее, потому что вы записываете на диск, а не делаете все это в памяти.Я сохранил шаг, когда python сжимает файл с помощью gzip перед загрузкой.Я сделал это, чтобы сэкономить место при загрузке;это особенно полезно, если вы загружаете таблицу с большим количеством повторяющихся данных.
В качестве отступления: вы должны не использовать это как есть в среде, где вы открытыв SQL-инъекцию;есть лучшие способы генерации команды COPY, если это является частью вашего варианта использования.