2010-04-23 15 views

risposta

13

Per connettersi a postgres da MATLAB, senza casella degli strumenti database di fare qualcosa di simile a:

% 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

Dalla mia esperienza, l'URL dovrebbe essere: url = 'jdbc: postgresql: // : /'; (la barra inversa tra '' e '' dovrebbe essere una barra diretta). Questo è mentre si esegue Matlab e il server PostgreSQL sullo stesso computer Windows 7. –

+1

Lo stesso per me su Linux. Il backslash non funziona, forwardslash lo fa. – luator

+0

Si consiglia di chiudere il ResultSet dopo aver terminato la lettura dei valori. Basta aggiungere rs.close(); per farlo –

0

MYSQL(additional link) lavoro per voi, almeno come punto di partenza?

+0

Purtroppo questo non funziona con postgresql. Ma probabilmente c'è una soluzione più generale via ODBC/JDBC? –

7

Come soluzione generale, è possibile utilizzare direttamente JDBC. I Matlab moderni hanno tutti una JVM incorporata in essi. Ottieni il file JAR del driver JDBC Postgresql sul tuo CLASSPATH Java in Matlab e puoi costruire la connessione JDBC e gli oggetti istruzione. Vedi "help javaclasspath".

Ci sono un paio di trucchi. La registrazione automatica delle classi di driver JDBC da JAR sul percorso di classe dinamico in Matlab sembra un po 'eccentrica, forse perché utilizza un classloader URL separato e le classi JDBC principali si trovano nel classloader di sistema. Quindi potrebbe essere necessario costruire esplicitamente delle istanze della classe di driver JDBC e passarle ai metodi JDBC, invece di usare la costruzione implicita del driver che si vede in tutte le esercitazioni JDBC. Inoltre, c'è un sovraccarico delle prestazioni con ogni chiamata al metodo Java fatta da Matlab, che può diventare costoso se si esegue il loop su un cursore del set di risultati in codice Matlab. Vale la pena scrivere un sottile strato di wrapper in Java che avvolgerà l'interfaccia iterativa di JDBC in un'interfaccia in stile Matlab orientata ai blocchi, leggendo i set di risultati e memorizzandoli in buffer in array in Java e passando tutti gli array a Matlab.

È possibile utilizzare anche ODBC, ma è necessario scrivere file MEX collegati a ODBC o lavorare con ADO. Più difficile e meno portabile.

MODIFICA: è probabile che la registrazione automatica dei driver funzioni correttamente se si ottengono i JAR sul classpath Java statico utilizzando un classpath.txt personalizzato.

+0

Sì, dovrebbe funzionare molto meglio della mia soluzione. – Jonas

1

ho avuto un problema di connessione a un database pgsql con MATLAB con modalità SSL. Usando la toolbox del database dovrebbe essere qualcosa del tipo: conn = database ('dbname', 'username', 'password', 'org.postgresql.Driver', 'jdbc: postgresql: databaseURL: dbname: ssl = true & sslfactory = org.postgresql.ssl.NonValidatingFactory & ')

ma ho avuto l'errore: 'FATAL: l'autenticazione della password riuscito per l'utente "username"'

Così ho utilizzare lo script e ottenere lo stesso errore.

ho dovuto aggiungere la riga

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

e l'url normale, non con sslfactory ... come detto nell'aiuto di MATLAB.

Quindi è bello, ma non riesco a utilizzare la funzione degli strumenti del database ... beh, non è un grosso problema!

Ci sono voluti un po 'di tempo per scoprirlo, quindi forse potrebbe essere utile per altri sapere che se hanno anche problemi di connessione a un database distante in modalità SSL.

grazie!

6

Prima di tutto, il collegamento nella parte superiore della domanda stessa è già rotto.Per quanto ne so, questa vecchia libreria pgmex non è più supportata. Ma esiste una nuovissima libreria client PostgreSQL ad alte prestazioni PgMex scritta al 100% in C e collegata alla più recente libpq di PostgreSQL 9.6.

Come è stato già sottolineato, è possibile utilizzare JDBC direttamente, ma secondo me è meglio, almeno per usare uno dei modi disponibili per accelerare l'esecuzione di query. Ad esempio, è possibile applicare qualcosa come descritto in un interessante articolo "Accelerare le query SQL Matlab-JDBC" pubblicato sul sito Web Matlab non documentato. Il motivo principale per una prestazione degradante del driver JDBC PostgreSQL è connesso a un significativo overhead di conversione dati da/verso formati nativi di Matlab (oggetti Java in Matlab e viceversa). Ma JDBC ha alcune limitazioni che non possono essere aggirate per insiemi di dati essenzialmente grandi. Può essere facilmente visto, ad esempio, se si ha a che fare con gli array. Vediamo la seguente tabella a confronto le prestazioni di inserimento dati relativi datainsert metodo dal Matlab Toolbox Database (lavorare con PostgreSQL vale a dire mediante una connessione JDBC diretta, in modo che possa essere considerato come rappresentante rilevante di connettori JDBC-based) con quello di batchParamExec dal PgMex indicato per il caso di array:

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

Qui n/a corrisponde alla quantità di dati che causa “su memoria heap Java” problema dato metodo di inserimento, Java dimensione heap per tutti questi esperimenti era pari a 939Mb . Per i risultati di questi e altri esperimenti presentati in forma grafica e per ulteriori dettagli sugli esperimenti, vedere il seguente "Performance comparison of PostgreSQL connectors in Matlab" article).

Quindi, se avete a che fare con i dati avendo semplici tipi scalari e di non molto grande volume, JDBC può pienamente soddisfare le vostre esigenze. Ma altrimenti è meglio IMHO usare le soluzioni basate su libpq come PgMex menzionate sopra. Oltre a PgMex, esiste, ad esempio, un pacchetto open source mexPostgres (lo puoi trovare sul sito web di Matlab Central) scritto in C++. Questa libreria analizza i dati basandosi sulla sua rappresentazione testuale (tramite la funzione PQgetvalue da libpq) e solo per un elenco molto limitato di tipi di dati (in realtà, sono numeri e logiche scalari, orari, date, timestamp e intervalli nonché stringhe , i tipi più complessi come gli array sono nuovamente fuori dal campo di applicazione). Ma il trasferimento tramite la rappresentazione del testo è molto lento e può essere riutilizzato solo per insiemi di dati non molto grandi. Ciò che riguarda PgMex, questa libreria implementa un canale di trasferimento dati binario molto efficiente tra Matlab e PostgreSQL senza alcuna analisi del testo. Inoltre, tutto è fatto in modo nativo e compatibile con Matlab (in una forma di matrici, matrici multidimensionali, strutture e altri formati Matlab arbitrari).

diamo un suggerimento su come affrontare il basando libreria quest'ultimo sulla esempio tratto da una delle risposte di cui sopra, ma riscritta utilizzando PgMex. Vale a dire, l'importazione dati è realizzata dalla seguente codice (si assume che nel seguente codice valori di tutti i parametri contrassegnati con <> segni siano propriamente riempiti come pure che la tabella corrispondente esiste già nel database):

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

Si prega di consultare la documentazione "getf" sul sito web PgMex per i dettagli concernenti il ​​modello del suo ingresso e di uscita argomenti (tra cui fieldSpecStr). Ogni elemento di outCVec contiene una struttura avente campi valueVec, isNullVec e isValueNullVec. Tutti questi campi hanno una dimensione lungo la prima dimensione che coincide con il numero di tuple recuperate, valueVec contiene valori del rispettivo campo di tabella , mentre isNullVec e isValueNullVec sono indicatori di NULL.

+0

Attenzione: non libero richiede la licenza anche per uso personale – ItsmeJulian

0

(NOTA BENE: ha bisogno di strumenti di database)
Ecco un esempio completo di un ready setup postgresql server da uno script MATLAB, regolare i parametri del database di conseguenza:

%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 

tuo utente ha bisogno ruolo dei diritti di accesso e essere in grado di accedere al tavoli (GRANT)

Problemi correlati