Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Подключение клиентов: psql, Python, JDBC

Что вы получите за 15 минут

После этого туториала у вас будут три рабочих способа подключения к локально запущенному инстансу AngaraBase:

  1. psql — интерактивная консоль PostgreSQL.
  2. Python через psycopg[binary] — типичный скрипт приложения.
  3. JDBC через стандартный org.postgresql:postgresql — типичный Java/Kotlin/Scala-стек.

Все три способа работают через стандартный pgwire-протокол: AngaraBase представляется клиентам как PostgreSQL, поэтому никаких специальных драйверов не требуется.

Это туториал, а не справочник

Здесь описан гарантированно работающий минимальный путь. Полный список протестированных клиентов и нюансы конкретных GUI-инструментов (DBeaver, IntelliJ DataGrip и др.) — в отдельном справочнике Совместимость клиентов.

Prerequisites

  • AngaraBase, поднятый локально по Quickstart. Считаем, что сервер слушает 127.0.0.1:5432, есть пользователь angara и база angara_demo.
  • Установленный psql (любая версия PostgreSQL ≥ 13).
  • Python 3.10+ (для шага 2).
  • JDK 17+ и Maven/Gradle (для шага 3).

Проверьте, что сервер отвечает:

psql --version
# psql (PostgreSQL) 16.4

ss -ltnp 'sport = 5432'
# LISTEN ... 127.0.0.1:5432 ...

Если порт не слушается — вернитесь к Quickstart и убедитесь, что angarabased запустился без ошибок.


Шаг 1. psql — интерактивная консоль

1.1. Подключение

psql 'postgresql://angara@127.0.0.1:5432/angara_demo'

Пароль (если задан) — по подсказке. Признак успеха: приглашение angara_demo=>.

1.2. Минимальный сценарий: создать таблицу, вставить, выбрать

-- Внутри psql:
CREATE TABLE products (
    id    BIGINT PRIMARY KEY,
    name  TEXT NOT NULL,
    price NUMERIC(10, 2) NOT NULL
);

INSERT INTO products (id, name, price) VALUES
    (1, 'Coffee', 4.50),
    (2, 'Tea',    3.00);

SELECT id, name, price FROM products ORDER BY id;

Ожидаемый вывод:

 id | name   | price
----+--------+-------
  1 | Coffee |  4.50
  2 | Tea    |  3.00
(2 rows)

1.3. Полезные \-команды

КомандаНазначение
\dtСписок пользовательских таблиц текущей базы.
\d productsСтруктура таблицы products (колонки, типы, индексы).
\duСписок ролей (RBAC).
\timing onВключить вывод времени каждого запроса.
\qВыйти из psql.

1.4. Если что-то пошло не так

  • could not connect to server: Connection refused — сервер не запущен или слушает не 127.0.0.1. Проверьте ss -ltnp 'sport = 5432' и логи angarabased.
  • authentication failed for user "angara" — пароль не задан или не совпадает. См. Аутентификация.
  • feature_not_supported (0A000) — вы попали в SQL-конструкцию, которую AngaraBase не поддерживает. Это явный fail-closed контракт; см. Известные ограничения и SQLSTATE.

Шаг 2. Python через psycopg

2.1. Установка драйвера

Используем psycopg версии 3 (бинарный wheel — без локальной компиляции):

python3 -m venv .venv
source .venv/bin/activate
pip install 'psycopg[binary]>=3.1,<4'

2.2. Минимальный скрипт

Создайте файл connect_demo.py:

import psycopg

DSN = "postgresql://angara@127.0.0.1:5432/angara_demo"

with psycopg.connect(DSN) as conn:
    with conn.cursor() as cur:
        cur.execute(
            "INSERT INTO products (id, name, price) VALUES (%s, %s, %s)",
            (3, "Espresso", 4.25),
        )
        cur.execute("SELECT id, name, price FROM products ORDER BY id")
        for row in cur.fetchall():
            print(row)
    conn.commit()

Запуск:

python3 connect_demo.py

Ожидаемый вывод:

(1, 'Coffee', Decimal('4.50'))
(2, 'Tea', Decimal('3.00'))
(3, 'Espresso', Decimal('4.25'))

2.3. Что важно знать про Python-клиент

  • Параметризованные запросы обязательны. Не подставляйте значения через f"...{value}..." — это путь к SQL-инъекциям. psycopg подставляет параметры на стороне драйвера через серверный prepared statement.
  • with conn: и conn.commit() — разные вещи. Контекст-менеджер with conn: гарантирует закрытие соединения, но не делает автокоммит. Транзакция фиксируется только явным conn.commit().
  • AngaraBase предсказуемо возвращает SQLSTATE. Перехватывайте psycopg.errors.FeatureNotSupported и проверяйте e.diag.sqlstate == "0A000", чтобы корректно обрабатывать неподдерживаемые конструкции (контракт fail-closed).

Шаг 3. JDBC через org.postgresql:postgresql

3.1. Зависимость

Maven (pom.xml):

<dependency>
  <groupId>org.postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>42.7.4</version>
</dependency>

Gradle (build.gradle.kts):

dependencies {
    implementation("org.postgresql:postgresql:42.7.4")
}

3.2. Минимальный класс

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class ConnectDemo {
    public static void main(String[] args) throws Exception {
        String url = "jdbc:postgresql://127.0.0.1:5432/angara_demo";
        java.util.Properties props = new java.util.Properties();
        props.setProperty("user", "angara");
        props.setProperty("preferQueryMode", "simple");

        try (Connection conn = DriverManager.getConnection(url, props)) {
            conn.setAutoCommit(false);

            try (PreparedStatement ps = conn.prepareStatement(
                    "INSERT INTO products (id, name, price) VALUES (?, ?, ?)")) {
                ps.setLong(1, 4L);
                ps.setString(2, "Cappuccino");
                ps.setBigDecimal(3, new java.math.BigDecimal("4.75"));
                ps.executeUpdate();
            }

            try (PreparedStatement ps = conn.prepareStatement(
                    "SELECT id, name, price FROM products ORDER BY id");
                 ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                    System.out.printf(
                            "%d %s %s%n",
                            rs.getLong("id"),
                            rs.getString("name"),
                            rs.getBigDecimal("price"));
                }
            }

            conn.commit();
        }
    }
}

3.3. Что важно знать про JDBC-клиент

  • preferQueryMode=simple — рекомендованный default для AngaraBase. Это отключает агрессивный probe-режим extended-protocol, который драйвер использует для совместимости с PostgreSQL-расширениями. AngaraBase реализует pgwire по контракту, и часть extended-protocol-проверок не нужна.
  • assumeMinServerVersion=9.0 — добавьте в props, если планируете работать через DBeaver/DataGrip; см. Совместимость клиентов → DBeaver.
  • Транзакции и setAutoCommit(false). AngaraBase реализует MVCC через UNDO-log; явные транзакции дают предсказуемый snapshot. Не оставляйте долгие транзакции открытыми — это замедляет AngaraGC.

Дальше