Извлечение данных из БД PostgreSQL без использования pg_dump - PullRequest
1 голос
/ 05 мая 2010

Существует база данных PostgreSQL, доступ к которой у меня ограничен (например, я не могу использовать pg_dump). Я пытаюсь создать локальное «зеркало» путем экспорта определенных таблиц из базы данных. У меня нет разрешений, необходимых для простого вывода таблицы в виде SQL из psql. Прямо сейчас у меня есть скрипт Python, который просматривает мои имена таблиц, выбирает все поля и затем экспортирует их как CSV:

for table_name, file_name in zip(table_names, file_names):
    cmd = """echo "\\\copy (select * from %s)" to stdout WITH CSV HEADER | psql -d remote_db | gzip > ./%s/%s.gz"""%(table_name,dir_name,file_name)
    os.system(cmd)

Я бы не хотел использовать CSV, если это возможно, поскольку я теряю типы полей и кодировка может быть испорчена. Во-первых, лучше всего было бы получить способ генерирования кода SQL для таблицы, используя \ copy. Следующим лучшим вариантом будет XML, в идеале с некоторым способом сохранения типов полей. Если это не сработает, я думаю, что последний вариант может быть двумя запросами - один для получения типов данных поля, другой для получения фактических данных.

Любые мысли или советы будут с благодарностью - спасибо!

Ответы [ 3 ]

3 голосов
/ 06 мая 2010

Меня озадачивает немного о "У меня нет прав, необходимых для простого вывода таблицы в виде SQL из psql." pg_dump работает автономно, вне psql (оба являются клиентами) и если у вас есть разрешение на подключение к базе данных и выбор таблицы, я думаю, вы также сможете ее сбросить, используя pg_dump -t <table>. Я что-то упустил?

2 голосов
/ 05 мая 2010

Если вы используете psycopg2, вы можете использовать cursor.description для проверки имен столбцов и использовать извлеченный тип данных для преобразования его в требуемую строку, например данные, в приемлемый формат.

Этот код создает INSERT операторов, которые вы можете использовать не только с PostgreSQL, но и с другими базами данных (тогда вам, вероятно, придется изменить формат даты):

cursor.execute("SELECT * FROM %s" % (table_name))
column_names = []
columns_descr = cursor.description
for c in columns_descr:
    column_names.append(c[0])
insert_prefix = 'insert into %s (%s) values ' % (table_name, ', '.join(column_names))
rows = cursor.fetchall()
for row in rows:
    row_data = []
    for rd in row:
        if rd is None:
            row_data.append('NULL')
        elif isinstance(rd, datetime.datetime):
            row_data.append("'%s'" % (rd.strftime('%Y-%m-%d %H:%M:%S') ))
        else:
            row_data.append(repr(rd))
    print('%s (%s);' % (insert_prefix, ', '.join(row_data)))

В psycopg2 есть даже поддержка COPY. Посмотрите на: COPY-связанные методы на их документах

Если вы предпочитаете использовать метаданные, вы можете использовать мой рецепт: Дамп схемы PostgreSQL db в текст . Он основан на извлечении информации META из PostgreSQL Лоренцо Альбертоном

1 голос
/ 05 мая 2010

Вы можете использовать эти запросы (полученные с помощью "psql --echo-hidden" и "\ d"), чтобы получить базовые метаданные:

-- GET OID
SET oid FROM pg_class WHERE relname = <YOUR_TABLE_NAME>

-- GET METADATA
SELECT a.attname,
  pg_catalog.format_type(a.atttypid, a.atttypmod),
  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
   FROM pg_catalog.pg_attrdef d
   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),
   a.attnotnull, a.attnum
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = <YOUR_TABLES_OID_FROM_PG_CLASS> AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum;

Это дает вам имя, тип данных, значение по умолчанию, нулевой флаг и порядок полей в строке. Чтобы получить реальные данные, лучше всего делать ставку CSV - встроенная таблица COPY TO STOOUT WITH CSV HEADER очень надежна. Но если вы беспокоитесь о кодировке, убедитесь, что получили значения server_encoding и client_encoding непосредственно перед сбросом данных CSV. Это в сочетании с метаданными из вышеприведенного запроса должно дать достаточно информации для правильной интерпретации дампа CSV.

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