Как я могу получить доступ к базе данных postgresql из matlab без набора инструментов базы данных matlabs? - PullRequest
5 голосов
/ 23 апреля 2010

Я уже пытался использовать pgmex . К сожалению, он не работает с libpq5 (Matlab сразу падает).

Ответы [ 6 ]

13 голосов
/ 13 января 2011

Для подключения к postgres из matlab без набора инструментов базы данных выполните что-то похожее на:

% Add jar file to classpath (ensure it is present in your current dir)
javaclasspath('postgresql-9.0-801.jdbc4.jar');

% Username and password you chose when installing postgres
props=java.util.Properties;
props.setProperty('user', '<your_postgres_username>');
props.setProperty('password', '<your_postgres_password>');

% Create the database connection (port 5432 is the default postgres chooses
% on installation)
driver=org.postgresql.Driver;
url = 'jdbc:postgresql://<yourhost>:<yourport>\<yourdb>';
conn=driver.connect(url, props);

% A test query
sql='select * from <table>'; % Gets all records
ps=conn.prepareStatement(sql);
rs=ps.executeQuery();

% Read the results into an array of result structs
count=0;
result=struct;
while rs.next()
    count=count+1;
    result(count).var1=char(rs.getString(2));
    result(count).var2=char(rs.getString(3));
    ...
end
6 голосов
/ 21 июля 2017

Прежде всего, ссылка вверху в самом вопросе уже сломана. Насколько я знаю, эта старая библиотека pgmex больше не поддерживается. Но есть совершенно новая высокопроизводительная клиентская библиотека PostgreSQL PgMex написан на 100% на C и связан с последней версией PostgreSQL 9.6 libpq.

Как уже указывалось, вы можете использовать JDBC напрямую, но, по-моему, лучше по крайней мере использовать один из доступных способов ускорить выполнение запросов. Например, вы можете применить что-то подобное описанной в интересной статье «Ускорение SQL-запросов Matlab-JDBC», опубликованной на недокументированном веб-сайте Matlab. Основная причина снижения производительности драйвера JDBC PostgreSQL связана со значительными накладными расходами на преобразование данных в / из собственных форматов Matlab (объекты Java в Matlab и наоборот). Но сам JDBC имеет определенные ограничения, которые нельзя обойти для существенно больших наборов данных. Это легко увидеть, например, если вам приходится иметь дело с массивами. Давайте посмотрим на следующую таблицу, сравнивающую производительность вставки данных метода datainsert из Matlab Database Toolbox (работающего с PostgreSQL именно через прямое соединение JDBC, так что его можно рассматривать как соответствующий представитель коннекторов на основе JDBC) с один из batchParamExec из упомянутого PgMex для случая массивов:

+-----------+-----------+--------------+------------------+
| Number of | Data size |   Time for   |     Time for     |
|   tuples  |           |  datainsert  |  batchParamExec  |
|           |           |    (sec.)    |      (sec.)      |
+-----------+-----------+--------------+------------------+
|   20000   |    23Mb   |    37.0255   |      1.1217      |
+-----------+-----------+--------------+------------------+
|   40000   |    46Mb   |    72.4008   |      2.2669      |
+-----------+-----------+--------------+------------------+
|   60000   |    69Mb   |   112.4428   |      3.2055      |
+-----------+-----------+--------------+------------------+
|   80000   |    92Mb   |      n/a     |      4.2073      |
+-----------+-----------+--------------+------------------+
|   100000  |   115Mb   |      n/a     |      5.5277      |
+-----------+-----------+--------------+------------------+
|   300000  |   346Mb   |      n/a     |      14.3530     |
+-----------+-----------+--------------+------------------+
|   600000  |   691Mb   |      n/a     |      28.3156     |
+-----------+-----------+--------------+------------------+
|   800000  |   922Mb   |      n/a     |      38.2579     |
+-----------+-----------+--------------+------------------+
|  1000000  |   1152Mb  |      n/a     |      47.8714     |
+-----------+-----------+--------------+------------------+
|  1200000  |   1382Mb  |      n/a     |      56.6258     |
+-----------+-----------+--------------+------------------+
|  1400000  |   1613Mb  |      n/a     |      65.9764     |
+-----------+-----------+--------------+------------------+
|  1750000  |   2016Mb  |      n/a     |      82.1829     |
+-----------+-----------+--------------+------------------+
|  2000000  |   2304Mb  |      n/a     |      93.5854     |
+-----------+-----------+--------------+------------------+

Здесь n/a соответствует объемам данных, которые вызывают проблему «нехватки памяти кучи Java» для данного метода вставки, размер кучи Java для всех этих экспериментов был равен 939 МБ. Результаты этих и других экспериментов, представленные в графической форме, а также подробности экспериментов см. В следующем Статья "Сравнение производительности коннекторов PostgreSQL в Matlab" ).

Таким образом, если вам приходится иметь дело с данными, имеющими простые скалярные типы и не очень большой объем, JDBC может полностью удовлетворить вас. Но в остальном ИМХО лучше использовать решения на основе libpq, такие как PgMex, упомянутые выше. Помимо PgMex, существует, например, пакет с открытым исходным кодом mexPostgres (вы можете найти его на веб-сайте Matlab Central), написанный на C ++. Эта библиотека анализирует данные на основе их текстового представления (с помощью функции PQgetvalue из libpq) и только для очень ограниченного списка типов данных (на самом деле это скалярные числа и логики, времена, даты, временные метки и интервалы, а также строки, более сложные типы, такие как массивы, снова выходят за рамки). Но передача через текстовое представление очень медленная и может использоваться снова только для не очень больших наборов данных. Что касается PgMex, эта библиотека реализует очень эффективный канал передачи двоичных данных между Matlab и PostgreSQL без разбора текста. Кроме того, все сделано в Matlab-дружественных и родным способом (в виде матриц, многомерные массивы, структуры и другие произвольные форматы Matlab).

Давайте дадим подсказку, как обращаться с последней библиотекой, основываясь на примере, взятом из одного из ответов выше, но переписанном с использованием PgMex. А именно, импорт данных осуществляется с помощью следующего кода (мы предполагаем, что в приведенном ниже коде значения всех параметров, отмеченных <>, заполнены правильно, а также что соответствующая таблица уже существует в базе данных):

% Create the database connection
dbConn=com.allied.pgmex.pgmexec('connect',[...
    'host=<yourhost> dbname=<yourdb> port=<yourport> '...
    'user=<your_postgres_username> password=<your_postgres_password>']);

% A test query
sql='select * from <table>'; % Gets all records
pgResult=com.allied.pgmex.pgmexec('exec',dbConn,sql); % Perform this test query

% Read the results
nFields=com.allied.pgmex.pgmexec('nFields',pgResult);
outCVec=cell(nFields,1);
fieldSpecStr='%<field_type_1> %<field_type_2> ...';
inpCVec=num2cell(0:nFields-1);
[outCVec{:}]=com.allied.pgmex.pgmexec('getf',pgResult,...
    fieldSpecStr,inpCVec{:});

Пожалуйста, смотрите документацию "getf" на веб-сайте PgMex для деталей относительно формата ввода. и выходные аргументы (включая fieldSpecStr). Каждый элемент outCVec содержит структуру, имеющую поля valueVec, isNullVec и isValueNullVec. Все эти поля имеют размер по первому измерению, совпадающему с числом извлеченных кортежей, valueVec содержит значения соответствующее поле таблицы, тогда как isNullVec и isValueNullVec являются индикаторами NULL.

6 голосов
/ 23 апреля 2010

Как общее решение, вы можете просто использовать JDBC напрямую.Современные Matlabs имеют встроенную JVM.Получите файл JAR драйвера JDBC Postgresql на вашем Java CLASSPATH в Matlab, и вы сможете создавать соединения JDBC и объекты операторов.См. "Help javaclasspath".

Есть пара ошибок.Автоматическая регистрация классов драйверов JDBC из JAR-файлов на динамическом пути к классам в Matlab кажется немного странной, возможно, потому, что в ней используется отдельный URL-загрузчик классов, а основные классы JDBC находятся в системном загрузчике классов.Поэтому вам может понадобиться явно создать экземпляры класса драйвера JDBC и передать их методам JDBC, вместо того чтобы использовать неявную конструкцию драйвера, которую вы видите во всех руководствах по JDBC.Кроме того, при каждом вызове метода Java, выполняемом из Matlab, снижается производительность, что может стать дорогостоящим, если вы зацикливаетесь на курсоре набора результатов в коде Matlab.Стоит написать тонкий слой-обертку в Java, который обернет итеративный интерфейс JDBC в блочно-ориентированный интерфейс в стиле Matlab, считывая наборы результатов и буферизируя их в массивах в Java, и передавая все массивы обратно в Matlab.

Вы также можете использовать ODBC, но для этого необходимо записать MEX-файлы, связанные с ODBC, или работать с ADO.Более сложный и менее переносимый.

РЕДАКТИРОВАТЬ: Вы, вероятно, можете заставить работать элементы автоматической регистрации драйверов, если вы получите JAR-файлы на вашем статическом пути к классам Java, используя пользовательский classpath.txt.

1 голос
/ 18 сентября 2014

У меня была проблема с подключением к базе данных pgsql с помощью matlab в режиме SSL.Используя набор инструментов базы данных, он должен выглядеть примерно так: conn = database ('dbname', 'username', 'password', 'org.postgresql.Driver', 'jdbc: postgresql: databaseURL: dbname: ssl = true & sslfactory = org.postgresql.ssl.NonValidatingFactory & ')

но у меня возникла ошибка:' FATAL: сбой аутентификации по паролю для пользователя 'username' '

Поэтому я использую ваш скрипт и получаю ту же ошибку.

Мне пришлось добавить строку

props.setProperty ('ssl', 'true');

и нормальный URL, а не с sslfactory ... как сказано вСправка по matlab.

Так что это хорошо, но я не могу использовать функцию набора инструментов базы данных ... ну, не так уж и много!

Мне понадобилось время, чтобы это выяснить, так что, возможно, другим было бы полезно знать, что если у них также есть проблемы с подключением к удаленной базе данных в режиме SSL.

спасибо!

0 голосов
/ 12 октября 2017

(ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: необходим набор инструментов базы данных)
Вот полный пример для готовой установки postgresql server из сценария matlab, соответственно измените параметры базы данных:

%Set preferences with setdbprefs.
setdbprefs('DataReturnFormat', 'cellarray');
setdbprefs('NullNumberRead', 'NaN');
setdbprefs('NullStringRead', 'null');


%Make connection to database.
%Using JDBC driver.
conn = database('mydb', 'USERNAME', 'YOURPASSWORD', 'Vendor',... 
  'POSTGRESQL', 'Server', 'SERVERIP', 'PortNumber', 5432);

%Read data from database, just an example on weather table in mydb database
curs = exec(conn, ['SELECT  weather.city'...
    ' , weather.temperature'...
    ' FROM  "mydb"."public".weather ']);

curs = fetch(curs);
close(curs);

%Assign data to output variable
untitled = curs.Data;

%Close database connection.
close(conn);

%Clear variables
clear curs conn

Вашему пользователю нужна роль прав ВХОДА и возможность доступа к таблицам ( GRANT )

0 голосов
/ 23 апреля 2010

Будет ли MYSQL (дополнительная ссылка) работать для вас, хотя бы в качестве отправной точки?

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