
PostgreSQL предоставляет встроенные типы данных JSON и JSONB, которые позволяют хранить структурированные данные прямо в таблицах. В Python для работы с ними чаще всего используют библиотеку psycopg2 или современный asyncpg, что обеспечивает удобное извлечение и сохранение JSON без ручного преобразования строк.
Для записи JSON из Python в Postgres важно учитывать формат данных: объекты Python dict и list автоматически конвертируются в JSON. Использование параметризованных запросов предотвращает ошибки сериализации и SQL-инъекции. Кроме того, при работе с JSONB можно использовать операторы Postgres для фильтрации и индексации, что ускоряет выборку больших массивов данных.
Практическая рекомендация – всегда проверять структуру данных перед вставкой. Например, вложенные объекты и массивы должны быть корректно сериализованы через json.dumps(), а при чтении из базы использовать json.loads() для восстановления Python-структур. Это снижает риск ошибок при последующей обработке и интеграции данных с внешними сервисами.
Установка и настройка библиотеки psycopg для работы с Postgres

Для работы с PostgreSQL в Python используется библиотека psycopg, актуальная версия которой – psycopg 3. Установка выполняется через pip:
pip install psycopg[binary]
Опция [binary] обеспечивает установку предварительно скомпилированного пакета, что ускоряет запуск и исключает необходимость сборки из исходников.
После установки подключение к базе создаётся с использованием класса psycopg.Connection. Пример минимальной конфигурации:
import psycopg
conn = psycopg.connect(
host='localhost',
dbname='mydb',
user='myuser',
password='mypassword'
)
Для безопасного выполнения запросов рекомендуется использовать контекстный менеджер и подготовленные выражения:
with conn.cursor() as cur:
cur.execute("SELECT data FROM my_table WHERE id = %s", (1,))
result = cur.fetchone()
Настройки соединения можно оптимизировать через параметры подключения:
port– порт сервера PostgreSQL (по умолчанию 5432);connect_timeout– время ожидания соединения в секундах;application_name– идентификатор клиента для логов сервера;sslmode– режим SSL-соединения (например,requireдля защищённого подключения).
Для работы с JSON-полями PostgreSQL psycopg автоматически преобразует их в Python-объекты при выборке и обратно при вставке, если использовать стандартный тип json или jsonb в базе.
После завершения операций соединение следует закрывать методом conn.close() или использовать контекстный менеджер для автоматического освобождения ресурсов.
Подключение к базе и выполнение запроса для извлечения данных

Для работы с PostgreSQL в Python рекомендуется использовать библиотеку psycopg2. Начнем с установки и импорта:
pip install psycopg2-binary
import psycopg2
Создание подключения требует указания хоста, имени базы, пользователя и пароля. Пример подключения:
conn = psycopg2.connect(
host="localhost",
database="example_db",
user="example_user",
password="example_pass"
)
Для выполнения запроса создаем объект курсора:
cur = conn.cursor()
Пример запроса для извлечения всех данных из таблицы users:
cur.execute("SELECT id, name, email FROM users")
Извлечение результата можно выполнить несколькими способами:
| Метод | Описание | Пример |
|---|---|---|
fetchone() |
Возвращает одну строку результата. | row = cur.fetchone() |
fetchall() |
Возвращает список всех строк. | rows = cur.fetchall() |
fetchmany(size) |
Возвращает указанное количество строк. | rows = cur.fetchmany(10) |
После завершения работы необходимо закрыть курсор и соединение:
cur.close()
conn.close()
Рекомендуется использовать конструкцию with для автоматического закрытия соединений:
with psycopg2.connect(host="localhost", database="example_db", user="example_user", password="example_pass") as conn:
with conn.cursor() as cur:
cur.execute("SELECT id, name, email FROM users")
rows = cur.fetchall()
Преобразование результатов запроса в формат JSON в Python

Для преобразования данных из PostgreSQL в JSON в Python чаще всего используют модуль psycopg2 совместно с json. Сначала выполняется SQL-запрос, затем результаты извлекаются и конвертируются в список словарей, пригодный для сериализации.
Пример подключения и выборки данных:
import psycopg2
import json
conn = psycopg2.connect(
dbname="mydb",
user="user",
password="password",
host="localhost",
port="5432"
)
cur = conn.cursor()
cur.execute("SELECT id, name, email FROM users;")
rows = cur.fetchall()
Для формирования JSON удобно использовать генерацию словарей через list comprehension:
columns = [desc[0] for desc in cur.description]
data = [dict(zip(columns, row)) for row in rows]
json_result = json.dumps(data, ensure_ascii=False)
print(json_result)
Советы по оптимизации:
- Использовать RealDictCursor из psycopg2 для автоматического получения словарей вместо кортежей.
- Применять параметр ensure_ascii=False для корректного отображения Unicode-символов.
- При больших объёмах данных использовать генераторы, чтобы избежать загрузки всех строк в память.
Пример с RealDictCursor:
from psycopg2.extras import RealDictCursor
cur = conn.cursor(cursor_factory=RealDictCursor)
cur.execute("SELECT id, name, email FROM users;")
data = cur.fetchall()
json_result = json.dumps(data, ensure_ascii=False)
Такой подход позволяет получать готовый JSON, который можно напрямую сохранять в файл или передавать в API.
Сохранение JSON в файл и управление кодировкой

Для записи данных из Postgres в файл JSON в Python используется модуль json. Рекомендуется явно указывать кодировку при работе с кириллицей или другими не-ASCII символами.
Пример записи JSON в файл с UTF-8:
import json
data = {'id': 1, 'name': 'Иван', 'email': 'ivan@example.com'}
with open('output.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
Аргумент ensure_ascii=False сохраняет символы в исходном виде, без Unicode-экранирования. Параметр indent=4 делает файл читаемым для человека.
Для записи больших объемов данных из Postgres удобен потоковый режим:
with open('output.json', 'w', encoding='utf-8') as f:
f.write('[')
for i, row in enumerate(cursor.fetchall()):
if i > 0:
f.write(',\\n')
json.dump(dict(row), f, ensure_ascii=False)
f.write(']')
Если требуется другая кодировка, например cp1251, ее нужно указать в параметре encoding при открытии файла. В этом случае ensure_ascii=False по-прежнему обеспечивает корректное сохранение локальных символов.
Для проверки корректности сохранения рекомендуется открыть файл в текстовом редакторе с выбранной кодировкой или использовать json.load() для чтения обратно в Python.
Обработка сложных структур данных и вложенных таблиц

При работе с PostgreSQL часто встречаются сложные структуры, такие как JSONB, массивы и вложенные таблицы. В Python для их обработки удобнее использовать библиотеку psycopg2 или asyncpg совместно с стандартным модулем json.
Пример запроса с вложенной структурой:
SELECT
users.id,
users.name,
json_agg(
json_build_object(
'order_id', orders.id,
'amount', orders.amount,
'products', (
SELECT json_agg(
json_build_object('product_id', p.id, 'name', p.name)
)
FROM products p
WHERE p.order_id = orders.id
)
)
) AS orders
FROM users
LEFT JOIN orders ON orders.user_id = users.id
GROUP BY users.id;
В Python результат запроса можно сразу преобразовать в JSON:
import psycopg2
import json
conn = psycopg2.connect("dbname=test user=postgres password=secret")
cur = conn.cursor()
cur.execute(open("nested_query.sql").read())
rows = cur.fetchall()
data = []
for row in rows:
data.append({
'id': row[0],
'name': row[1],
'orders': row[2] # уже JSON-структура из запроса
})
with open('output.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
Рекомендации при работе с вложенными данными:
- Использовать
json_aggиjson_build_objectдля формирования структур на стороне PostgreSQL – это уменьшает объем преобразований в Python. - При больших таблицах применять
LIMITи постраничную выборку (OFFSET) для предотвращения загрузки всей базы в память. - Массивы и JSONB лучше извлекать с помощью
cur.fetchall(), а затем работать с ними как со словарями и списками Python. - Если данные содержат многомерные вложенные структуры, сначала нормализовать их через подзапросы или CTE, чтобы упростить последующую сериализацию.
- Для больших JSON-файлов использовать
json.dump(..., indent=4)с поэтапной записью через генераторы, чтобы снизить нагрузку на память.
Такой подход обеспечивает точное соответствие вложенной структуры PostgreSQL и результирующего JSON, облегчает дальнейшую обработку и интеграцию с другими сервисами.
Отправка JSON напрямую в веб-приложение или API

Для передачи данных из PostgreSQL в веб-приложение или API Python предоставляет библиотеку `requests`. После извлечения и сериализации данных в JSON используется метод `POST` для отправки информации.
Пример кода для отправки JSON в API:
import psycopg2
import json
import requests
Подключение к базе данных
conn = psycopg2.connect(
dbname="example_db",
user="user",
password="password",
host="localhost",
port="5432"
)
cur = conn.cursor()
Получение данных и преобразование в словарь
cur.execute("SELECT id, name, email FROM users;")
rows = cur.fetchall()
data = [{"id": r[0], "name": r[1], "email": r[2]} for r in rows]
Сериализация в JSON
json_data = json.dumps(data)
Отправка POST-запросом в API
response = requests.post(
"https://example.com/api/users",
headers={"Content-Type": "application/json"},
data=json_data
)
print(response.status_code, response.text)
cur.close()
conn.close()
Рекомендации при работе с JSON и API:
1. Устанавливайте `Content-Type: application/json`, чтобы сервер корректно распознал формат данных.
2. Для больших наборов данных используйте пакетную отправку (batch) или стриминг, чтобы избежать перегрузки памяти и таймаутов.
3. Проверяйте статус ответа сервера: коды 2xx означают успешную обработку, 4xx и 5xx – ошибки на стороне клиента или сервера.
4. При необходимости добавляйте аутентификацию (Bearer-токен или Basic Auth) через заголовки.
5. Для регулярной отправки данных используйте функции или cron-задачи, чтобы автоматизировать процесс и минимизировать ручные операции.
Вопрос-ответ:
Какая разница между типами данных json и jsonb в Postgres?
Тип json хранит данные как текст и проверяет корректность JSON при вставке, но поиск по содержимому может быть медленным. Тип jsonb хранит данные в бинарном виде, что ускоряет фильтрацию и индексацию. Если планируется частый поиск и обновление JSON-данных, предпочтительнее использовать jsonb, а если важна точная сохранность форматирования — json.
