Прямые запросы из PostgreSQL к MongoDB

Используемые термины: PostgreSQL, MongoDB, Linux.
Отправка запросов из PostgreSQL к MongoDB может быть выполнена с помощью расширения mongo_fdw. В данной инструкции мы рассмотрим процесс его сборки, установки и использования на системе Linux.
Расширение mongo_fdw на момент обновления инструкции поддерживало PostgreSQL версий с 10 по 15. Мы рассмотрим процесс на примере версии 13, однако важно отметить, что набор команд от этого сильно не меняется.
Предполагается, что у нас уже установлены серверы с PostgreSQL и MongoDB. Ссылки на подробные инструкции, как это сделать будут приведены в конце инструкции. Сборку и установку расширения mongo_fdw мы будем выполнять на сервере с PostgreSQL, а MongoDB может быть установлен на том же сервере или на другом, к которому есть сетевой доступ.
Инсталляция компонентов
Пакеты, нужные для сборки
Установка cmake
Сборка расширения mongo_fdw
Загрузка исходных файлов
Сборка mongo-c
Сборка json-c
Сборка mongo_fdw
Тест подключения к базе MongoDB
Решение проблем
Дополнительная информация
Установка необходимых компонентов
Процесс сборки mongo_fdw включает несколько этапов, на каждом из которые потребуются свои программные компоненты. Рассмотрим их установку.
Пакеты
Для выполнения необходимых сборок нам нужно установить некоторые пакеты, состав которых для разных дистрибутивов Linux будет отличаться.
а) системы Deb:
apt update
apt install git wget postgresql-server-dev-13
б) системы RPM:
yum install git wget postgresql13-devel
* где:
- git — утилита для работы с репозиториями на основе git.
- wget — приложение, позволяющее выполнить загрузку файлов.
- postgresql-server-dev-13 / postgresql13-devel — набор библиотек, необходимые для сборки пакетов, которые используют функции postgresql.
CMake
CMake является универсальной программой, которая читает в исходниках файл CMakeLists.txt и создает на его основе файлы сборки. Также его называют кроссплатформенным make.
Нам нужно, чтобы в системе был установлен CMake версии 3.1 или выше. В зависимости от ситуации, наши действия будут отличаться.
Установка из пакетов
Проще всего установить CMake, используя менеджер пакетов yum или apt.
а) на системах Deb:
apt search --names-only '^cmake$'
apt install cmake
* первая команда покажет, какой версии cmake будет установлен. Второй командой мы уже можем выполнить установку.
б) на системах RPM:
yum install cmake
* менеджер пакетов покажет версию, которую будет устанавливать система. Если она соответствует требованиям, отвечаем y.
Сборка CMake
Если мы не можем установить из репозитория нужную версию пакета cmake, мы можем его собрать из исходников.
Установим необходимые для этого пакеты.
а) на системах Deb:
apt install gcc g++
б) на системах RPM:
yum install gcc gcc-c++ openssl-devel
* где:
- gcc — коллекция компиляторов для C.
- g++ / gcc-c++ — коллекция компиляторов для C++.
- libssl-dev / openssl-devel — файлы для сборки приложений, которые будут использовать OpenSSL.
Переходим на страницу проекта CMake в гитхабе и копируем ссылку на последнюю стабильную версию архива (не rc):
Переходим в каталог для хранения исходников:
cd /usr/local/src
Используя скопированную ссылку, скачиваем данных архив:
wget https://github.com/Kitware/CMake/releases/download/v3.25.2/cmake-3.25.2.tar.gz
Распакуем архив:
tar -zxf cmake-*.tar.gz
Переходим в распакованный каталог:
cd cmake-*/
Выполняем подготовку исходников к сборке:
./bootstrap
Выполняем сборку:
make
Выполняем установку:
make install
Чтобы текущая оболочка пользователя подхватила новый путь до cmake, выполняем повторый ее запуск:
bash
И посмотрим версию установленной cmake:
cmake --version
Если команда вернут ошибку bash: cmake: command not found, можно создать такой симлинк:
ln -s /usr/local/bin/cmake /usr/bin/cmake
В моем случае было:
cmake version 3.25.2
...
Сборка mongo_fdw
Как говорилось выше, сборка расширения mongo_fdw будет разбита на несколько этапов:
- Загрузка исходника.
- Сборка mongo-c.
- Сборка json-c.
- Сборка mongo_fdw.
Рассмотрим их по-отдельности.
Загрузка исходников mongo_fdw
Сборка как mongo_fdw, так и дополнительных компонентов будет выполняться в каталоге с исходником нашего расширения. Поэтому сначала мы должны его загрузить.
Перейдем в специализированный для этого каталог:
cd /usr/local/src/
Выполняем команду:
git clone https://github.com/EnterpriseDB/mongo_fdw.git
Переходим в каталог mongo_fdw:
cd mongo_fdw
Сборка mongo-c
Mongo-c представляет из себя набор библиотек для использования MongoDB из приложений C. Нам нужны эти библиотеки для сборки расширения.
Переходим на страницу проекта и копируем ссылку на архив mongo-c-driver.
Используя ссылку, скачиваем архив:
wget https://github.com/mongodb/mongo-c-driver/releases/download/1.23.2/mongo-c-driver-1.23.2.tar.gz
Распакуем его:
tar -zxf mongo-c-driver-*.tar.gz
В каталоге расширения уже может быть папка mongo-c-driver — удаляем ее:
rm -rf mongo-c-driver
Переименуем каталог, созданный после распаковки в mongo-c-driver:
mv mongo-c-driver-*/ mongo-c-driver
Переходим в него:
cd mongo-c-driver
Выполняем конфигурирование драйвера mongo:
cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF .
Задаем каталог установки:
cmake -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF .
* обратите внимание, что необходимые файлы и библиотеки будут установлены в каталог /usr.
Собираем файлы для установки:
cmake --build .
Если мы получим ошибку ... error: ‘for’ loop initial declarations are only allowed in C99 mode, необходимо добавить опцию, использующую стандарт 99).
Выполняем установку:
cmake --build . --target install
Сборка json-c
Компонент json-c позволяет выполнять различные действия в языке C в формате JSON. Его также необходимо собрать для нашего расширения.
На странице со списком версий выбираем нужную или последнюю. Копируем ссылку для загрузки архива:
После установки mongo-c-driver мы должны остаться в каталоге с его исходниками. Выходим из нее:
cd ..
Скачиваем архив по скопированной ссылке:
wget https://github.com/json-c/json-c/archive/refs/tags/json-c-0.16-20220414.tar.gz
Распакуем его:
tar -zxf json-c-*.tar.gz
Переименуем каталог, созданный после распаковки в json-c:
mv json-c-*/ json-c
Переходим в него:
cd json-c
Выполняем конфигурирование исходника:
cmake .
Задаем префикс для установки пакета (в каталог /usr):
cmake -DCMAKE_INSTALL_PREFIX=/usr .
Собираем пакет и устанавливаем его:
make
make install
Сборка mongo_fdw
Возвращаемся в каталог с исходниками нужного расширения:
cd ..
Укажем с помощью системной переменной PKG_CONFIG_PATH путь до библиотек mongo-c-driver:
export PKG_CONFIG_PATH=/usr/local/src/mongo-c-driver/src/libmongoc/src:/usr/local/src/mongo-c-driver/src/libbson/src
PostgreSQL может быть установлен в разные каталоги. Все зависит от его версии и типа дистрибутива Linux. Также PostgreSQL и Postgrespro могут использовать, принципиально, разные пути. Компилятору нужно знать, где искать приложение pg_config, которое идет в составе с PostgreSQL и выводит информацию по конфигурационным параметрам СУБД.
Для поиска приложения в нашей системе вводим команду:
find / -name pg_config
В моем случае ответ был такой:
/usr/pgsql-13/bin/pg_config
Таким образом, в каталоге /usr/pgsql-13/bin находится нужная нам программ. Указываем это с помощью системной переменной PATH:
export PATH=/usr/pgsql-13/bin:$PATH
Выполняем компиляцию расширения:
make USE_PGXS=1
И установку.
make USE_PGXS=1 install
Готово.
Проверка подключения к MongoDB
Предположим, что наш сервер MongoDB:
- находится на узле с IP-адресом 192.168.0.15.
- имеет коллекцию documents в базе users_db.
- для подключения требует ввести логин user и пароль passwd.
На сервере с PostgreSQL подключаемся к командной оболочке sql:
su - postgres -c "psql"
Создаем расширение mongo_fdw:
# CREATE EXTENSION mongo_fdw;
Создаем привязку к серверу mongo — адрес 192.168.0.15, порт 27017:
# CREATE SERVER mongo_server FOREIGN DATA WRAPPER mongo_fdw OPTIONS (address '192.168.0.15', port '27017');
* привязка будет иметь название mongo_server и использовать расширение mongo_fdw.
Задаем аутентификационные данные для подключения к привязке mongo_server, созданной выше:
# CREATE USER MAPPING FOR postgres SERVER mongo_server OPTIONS (username 'user', password 'passwd');
* в нашем примере мы используем пользователя user с паролем passwd. В вашем случае это должны быть реальные данные для подключения к mongo.
Создаем внешнюю таблицу:
# CREATE FOREIGN TABLE mongotest (
_id name,
foreign_id int,
foreign_name text,
foreign_created timestamptz
)
SERVER mongo_server
OPTIONS (database 'users_db', collection 'documents');
* в данном примере мы создаем внешнюю таблицу с названием mongotest. Она будет привязываться с таблице в mongo с названием users_db и коллекции documents.
Попробуем сделать запрос:
# SELECT * FROM mongotest;
Если коллекция, к которой мы подключились не пустая, мы должны увидеть данные.
Возможные проблемы
Error: ‘for’ loop initial declarations are only allowed in C99 mode
Данную ошибку мы можем получить при билдовании mongo-c-driver.
Причина: в более новых версиях cmake используется код, учитывающий стандарт языка программирования C — C99. Нам необходимо добавить в опции компиляции строку, которая будет также учитывать данный стандарт.
Решение: находясь в каталоге с исходником открываем файл:
vi CMakeLists.txt
Добавляем в верх (после cmake_minimum_required):
cmake_minimum_required (VERSION 3.1)
set(CMAKE_C_STANDARD 99)
...
Снова запускаем компиляцию.
Читайте также
Другие полезные материалы, связанные с данной инструкцией:
1. Установка и запуск PostgreSQL на Ubuntu.
2. Установка и запуск PostgreSQL на CentOS.