Скопируйте данные из Postgres DB в AWS S3 за один шаг - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть сценарий использования для перемещения выбранных данных из Postgres в Amazon S3.Это должно произойти за один шаг.Я пишу Java-программу, чтобы сделать это.

Я нашел способ скопировать данные в 2 этапа.Я использую библиотеку CopyManager и метод copyOut, чтобы получить данные в моем локальном.После этого я перемещаю тот же файл в S3, используя Java.

postgres код для передачи данных в мой локальный

CopyManager copyManager = new CopyManager((BaseConnection) con);
FileWriter fileWriter = new FileWriter("file.csv");
copyManager.copyOut("COPY (SELECT stmt) TO STDOUT WITH DELIMITER '\t' CSV HEADER", fileWriter);

код AWS для перехода с локального на S3

AmazonS3 conn = new AmazonS3Client(credentials);
conn.setEndpoint("xxx.com");
conn.putObject(
            bucket1.getName(),
            "request.json",
            new File("file.csv")
    );

Я ожидаю, что это произойдет за один раз вместозаписи в файл, а затем переместить файл на S3.

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Вы должны использовать PutObject с InputStream.

. Вы можете использовать PipedOutputStream и PipedInputStream , чтобы перенаправить вывод на вход putObject

PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);

Используйте in в качестве аргумента для PutObject и начните запись в out в другом потоке.

0 голосов
/ 08 января 2019

Если вы готовы сделать это в 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, если это является частью вашего варианта использования.

0 голосов
/ 21 декабря 2018

Я не пробовал это, но я думаю, что вы должны быть в состоянии сделать это.

Вместо того, чтобы передавать FileWriter на copyOut(), вы можете передать любое OutputStream.Вы также можете предоставить InputStream методу putObject вместо файла.

Так что вам просто нужно конвертировать OutputStream в InputStream, для которого есть ряд методов (например, см. этот пост ), или вы можете использовать что-то вроде EasyStream library .

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...