2010-04-23 2 views

Répondre

13

Pour vous connecter à postgres de Matlab sans la boîte à outils de base de données similaire à faire quelque chose:

% 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 
+5

D'après mon expérience, l'URL doit être: url = 'jdbc: postgresql: // : /'; (le backslash entre '' et '' devrait être une barre oblique). C'est en cours d'exécution Matlab et le serveur PostgreSQL sur le même ordinateur Windows 7. –

+1

Pareil pour moi sur Linux. Backslash ne fonctionne pas, forwardslash le fait. – luator

+0

Il est recommandé de fermer le ResultSet une fois que vous avez fini de lire les valeurs. Ajoutez simplement rs.close(); pour ce faire –

0

Est-ce que MYSQL(additional link) travaillerait pour vous, au moins comme point de départ?

+0

Malheureusement, cela ne fonctionne pas avec postgresql. Mais il y a probablement une solution plus générale via ODBC/JDBC? –

7

En règle générale, vous pouvez simplement utiliser JDBC directement. Les Matlabs modernes ont tous une JVM intégrée. Obtenez le fichier JAR du pilote JDBC Postgresql sur votre CLASSPATH Java dans Matlab et vous pouvez créer des objets de connexion et d'instruction JDBC. Voir "help javaclasspath".

Il y a quelques getchas. L'enregistrement automatique des classes de pilotes JDBC à partir des fichiers JAR sur le chemin de classe dynamique dans Matlab semble un peu bizarre, peut-être parce qu'il utilise un chargeur de classe d'URL distinct et que les classes JDBC principales se trouvent dans le chargeur de classe système. Il se peut donc que vous deviez explicitement construire des instances de la classe de pilote JDBC et les transmettre aux méthodes JDBC, au lieu d'utiliser la construction de pilote implicite que vous voyez dans tous les didacticiels JDBC. De plus, chaque appel de méthode Java fait à partir de Matlab entraîne des pertes de performances, ce qui peut devenir coûteux si vous faites une boucle sur un curseur de jeu de résultats dans le code Matlab. Cela vaut la peine d'écrire une couche wrapper fine en Java qui encapsule l'interface itérative de JDBC dans une interface de type Matlab orientée bloc, en lisant dans les ensembles de résultats et les buffers dans des tableaux en Java, et en renvoyant les tableaux entiers à Matlab.

Vous pouvez également utiliser ODBC, mais cela nécessite l'écriture de fichiers MEX liés à ODBC ou fonctionnant avec ADO. Plus difficile et moins portable.

EDIT: Vous pouvez probablement faire en sorte que l'enregistrement automatique des pilotes fonctionne correctement si vous obtenez les fichiers JAR sur votre classpath Java statique en utilisant un classpath.txt personnalisé.

+0

Oui, cela devrait fonctionner beaucoup mieux que ma solution. – Jonas

1

J'ai eu un problème de connexion à une base de données pgsql avec Matlab avec le mode SSL. En utilisant la boîte à outils de base de données, il devrait ressembler à ceci: conn = base de données ('nombase', 'nom d'utilisateur', 'mot de passe', 'org.postgresql.Driver', 'jdbc: postgresql: base de donnéesUR: nombase: ssl = true & sslfactory = org.postgresql.ssl.NonValidatingFactory & «)

mais j'avais l'erreur: « FATAL: l'authentification par mot de passe a échoué pour l'utilisateur « nom d'utilisateur » »

J'utiliser votre script et obtenir la même erreur.

J'ai dû ajouter la ligne

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

et l'URL normale, pas avec sslfactory ... comme indiqué dans le matlab aide. Donc, c'est bien, mais je ne peux pas utiliser la fonction de la boîte à outils de la base de données ... eh bien, pas si grave! Il m'a fallu du temps pour le savoir, alors peut-être que ça pourrait être utile pour les autres de savoir que s'ils ont aussi des problèmes pour se connecter à une base de données distante en mode SSL.

merci!

6

Tout d'abord, le lien en haut de la question est déjà rompu.Pour autant que je sache, cette ancienne bibliothèque pgmex n'est plus supportée. Mais il y a une toute nouvelle bibliothèque client PostgreSQL haute performance PgMex écrite à 100% en C et liée à la dernière libpq PostgreSQL 9.6.

Comme déjà souligné, vous pouvez utiliser JDBC directement, mais à mon humble avis, il vaut mieux au moins utiliser l'une des méthodes disponibles pour accélérer l'exécution des requêtes. Par exemple, vous pouvez appliquer quelque chose comme décrit dans un article intéressant "Accélérer les requêtes SQL Matlab-JDBC" publié sur le site Web Undocumented Matlab. La principale raison d'une dégradation des performances du pilote JDBC de PostgreSQL ™ est liée à un surcoût significatif de conversion de données vers/depuis les formats Matlab natifs (objets Java vers Matlab et vice versa). Mais JDBC a lui-même certaines limitations qui ne peuvent pas être traitées pour des ensembles de données essentiellement volumineux. Il peut être facilement vu, par exemple, si vous devez traiter avec des tableaux. Regardons le tableau suivant comparant les performances d'insertion de données de la méthode datainsert de Matlab Database Toolbox (fonctionnant avec PostgreSQL, à savoir via une connexion JDBC directe, afin qu'elle puisse être considérée comme un représentant pertinent des connecteurs basés sur JDBC) avec celle de batchParamExec du mentionné PgMex pour le cas des tableaux:

 
+-----------+-----------+--------------+------------------+ 
| 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  | 
+-----------+-----------+--------------+------------------+ 

ici n/a correspond à des volumes de données qui cause « de mémoire de tas Java » problème pour la méthode d'insertion donné, Java taille du tas pour toutes ces expériences était égale à 939Mb . Pour les résultats de ces expériences et d'autres présentées sous forme graphique ainsi que pour d'autres détails d'expériences, veuillez consulter les documents suivants: "Performance comparison of PostgreSQL connectors in Matlab" article). Par conséquent, si vous devez traiter des données ayant des types scalaires simples et un volume pas très important, JDBC peut vous satisfaire pleinement. Mais sinon, il vaut mieux à mon humble avis d'utiliser des solutions basées sur libpq comme PgMex mentionné ci-dessus. Outre PgMex, il existe, par exemple, un paquet open-source mexPostgres (vous pouvez le trouver sur le site de Matlab Central) écrit en C++. Cette librairie analyse les données en fonction de sa représentation textuelle (via la fonction PQgetvalue de libpq) et seulement pour une liste très limitée de types de données (en fait, ce sont des numériques scalaires et logiques, des temps, des dates, des horodatages et des chaînes) , les types plus complexes tels que les tableaux sont à nouveau hors de la portée). Mais le transfert via la représentation textuelle est très lent et ne peut être utilisé que pour des ensembles de données pas très volumineux. En ce qui concerne PgMex, cette bibliothèque implémente un canal de transfert de données binaires très efficace entre Matlab et PostgreSQL sans aucune analyse de texte. En outre, tout est fait en mode Matlab-amical et natif (sous la forme de matrices, tableaux multidimensionnels , structures et autres formats Matlab arbitraires). Donnons un indice sur la façon de traiter cette dernière bibliothèque en nous basant sur l'exemple tiré de l'une des réponses ci-dessus, mais réécrites à l'aide de PgMex. A savoir, l'importation de données est mis en œuvre par le code suivant (nous supposons que dans le code ci-dessous des valeurs de tous les paramètres marqués par <> signes sont correctement remplis aussi bien que la table correspondante existe déjà dans la base de données):

% 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{:}); 

Veuillez consulter la documentation "getf" sur le site Web de PgMex pour les détails concernant le format de son entrée et les arguments de sortie (y compris fieldSpecStr). Chaque élément de outCVec contient une structure ayant les zones valueVec, isNullVec et isValueNullVec. Tous ces champs ont une taille le long de la première dimension coïncidant avec le nombre de tuples retrivés, valueVec contient les valeurs du champ de table respectif , alors que isNullVec et isValueNullVec sont des indicateurs de valeurs NULL.

+0

méfiez-vous: non-libre nécessite une licence même pour un usage personnel – ItsmeJulian

0

(DISCLAIMER: a besoin boîte à outils de base de données)
Voici un exemple complet à un ready setup postgresql server à partir d'un script Matlab, régler les paramètres de base de données en conséquence:

%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 

Votre utilisateur a besoin des droits LOGIN rôle et être en mesure d'accéder à la tables (GRANT)

Questions connexes