- Undocumented Matlab - https://undocumentedmatlab.com -

Using SQLite in Matlab

Posted By Yair Altman On December 27, 2017 | 5 Comments

MathWorks invests a huge amount of effort in recent years on supporting large distributed databases. The business case for this focus is entirely understandable, but many Matlab users have much simpler needs, which are often served by the light-weight open-source SQLite database [1] (which claims to be the most widely-used database worldwide). Although SQLite is very widely used, and despite the fact that built-in support for SQLite is included in Matlab (for its internal use), MathWorks has chosen not to expose any functionality or wrapper function that would enable end-users to access it. In any case, I recently came across a need to do just that, when a consulting client asked me to create an interactive data-browser for their SQLite database that would integrate with their Matlab program:

SQLite data browser

In today’s post I will discuss several possible mechanisms to integrate SQLite in Matlab code, and you can take your pick among them. Except for the Database Toolbox, all the alternatives are free (open-source) libraries (even the commercial Database Toolbox relies on one of the open-source libraries, by the way).

sqlite4java

sqlite4java is a Java package by ALM Works [2] that is bundled with Matlab for the past several years (in the %matlabroot%/java/jarext/sqlite4java/ folder). This is a lightweight open-source package that provides a minimalist and fast (although not very convenient) interface to SQLite. You can either use the package that comes with your Matlab installation, or download and use the latest version from the project repository [3], where you can also find documentation.
Mark Mikofski exposed [4] this hidden nugget back in 2015, and you are welcome to view his post for additional details. Here’s a sample usage:

% Open the DB data file
db = com.almworks.sqlite4java.SQLiteConnection(java.io.File('C:\Yair\Data\IGdb 2017-11-13.sqlite'));
db.open;
% Prepare an SQL query statement
stmt = db.prepare(['select * from data_table where ' conditionStr]);
% Step through the result set rows
row = 1;
while stmt.step
   numericValues(row) = stmt.columnInt(0);    % column #0
   stringValues{row}  = stmt.columnString(1); % column #1
end
% Cleanup
stmt.dispose
db.dispose

Note that since sqlite4java uses a proprietary interface (similar, but not identical, to JDBC), it can take a bit of time to get used to it. I am generally a big fan of preferring built-in components over externally-installed ones, but in this particular case I prefer other alternatives.

JDBC

JDBC [5] (Java Database Connectivity) is the industry standard for connectivity to databases. Practically all databases nowadays have at least one JDBC connector, and many DBs have multiple JDBC drivers created by different groups. As long as they all adhere to the JDBC interface standard, these drivers are all equivalent and you can choose between them based on availability, cost, support, license, performance and other similar factors. SQLite is no exception to this rule, and has several JDBC driver implementations, including xerial’s sqlite-jdbc [6] (also discussed by Mark Mikofski [4]) and sqlitejdbc [7]. If you ask me,
sqlite-jdbc is better as it is being maintained with new versions released periodically.
The example above would look something like this with sqlite-jdbc:

% Add the downloaded JAR library file to the dynamic Java classpath
javaaddpath('C:\path\to\sqlite\sqlite-jdbc-3.21.0.jar')
% Open the DB file
jdbc = org.sqlite.JDBC;
props = java.util.Properties;
conn = jdbc.createConnection('jdbc:sqlite:C:\Yair\Data\IGdb 2017-11-13.sqlite',props);  % org.sqlite.SQLiteConnection object
% Prepare and run an SQL query statement
sqlStr = ['select * from data_table where ' conditionStr];
stmt = conn.createStatement;     % org.sqlite.jdbc4.JDBC4Statement object
rs = stmt.executeQuery(sqlStr);  % org.sqlite.jdbc4.JDBC4ResultSet object
% Step through the result set rows
rows = 1;
while rs.next
   numericValues(row) = rs.getLong('ID');
   stringValues{row}  = rs.getString('Name');
end
% Cleanup
rs.close
stmt.close
conn.close

Database toolbox

In addition to all the above, MathWorks sells the Database Toolbox which has an integral SQLite connector [8], in two flavors – native and JDBC (the JDBC connector is simply sqlite-jdbc that I mentioned above, see a short discussion here [9]).
I assume that the availability of this feature in the DB toolbox is the reason why MathWorks has never created a documented wrapper function for the bundled sqlite4java. I could certainly understand this from a business perspective. Still, with so many free alternatives available as discussed in this post, I see not reason to purchase the toolbox merely for its SQLite connector. Then again, if you need to connect to several different database types, not just SQLite, then getting the toolbox might make sense.

mksqlite

My personal favorite is actually none of these Java-based connectors (surprise, surprise), but rather the open-source mksqlite connector [10] by Martin Kortmann [11] and Andreas Martin [12]. This is a native (Mex-file) connector that acts as a direct Matlab function. The syntax is pretty straight-forward and supports SQL queries. IMHO, its usage is a much simpler than with any of the other alternatives:

% Open the DB file
mksqlite('open', 'C:\Yair\Data\IGdb 2017-11-13.sqlite');
% Query the database
results = mksqlite(['select * from data_table where ' conditionStr]);
numericValues = [results.ID];
stringValues  = {results.Name};
% Cleanup
mksqlite('close');

Can it be any simpler than this!?
However, the main benefit of mksqlite over the other connectors is not its simplicity but the connector’s speed. This speed is due to the fact that the query is vectorized and we do not need to loop over all the separate data rows and fields. With the other connectors, it is actually not the loop that takes so long in Matlab, but rather the overheads and inefficiencies of numerous library calls to fetch one single value at a time from the result-set – this is avoided in mksqlite where there is only a single call. This results in lightning speed: A couple of years ago I consulted to a client who used a JDBC connector to an SQLite database; by switching from a JDBC connector to mksqlite, I reduced the execution time from 7 secs to 70 msecs – a 100x speedup! In that specific case, this made the difference between an unusable program and a highly interactive/responsive one.

Other alternatives

In addition to all the above, we can also use a .NET-based connector [13] or a Python one [14] – I leave these as an exercise for the reader…
Have I forgotten some important alternative? Or perhaps you have have some related tip you’d like to share? If so, then please leave a comment below.
Happy New Year everybody!

Categories: Java, Low risk of breaking in future versions, Undocumented feature


5 Comments (Open | Close)

5 Comments To "Using SQLite in Matlab"

#1 Comment By Andrea Carignano On December 12, 2019 @ 10:12

Thank you very much!
I am using the first method of this article: sqlite4java.
I have just a little problem. After every operation on database, I get some red messages in the command line like this:

dic 12, 2019 8:56:09 AM com.almworks.sqlite4java.Internal log

INFORMAZIONI: [sqlite] DB[2]: opened

how can I turn off these messages?

#2 Comment By Yair Altman On December 12, 2019 @ 10:21

Andrea – sqlite4java is an open-source project ( [21]). You can modify its code and/or submit an issue on that project’s repo ( [22]).

#3 Comment By Philip Howard On January 29, 2020 @ 16:16

Yair,

Thank you for your post. Is it possible to use Matlab functions inside the SQL query for method using sqlite-jdbc? I see here that you can create custom callback functions in Java: [23]. And Matlab let’s call it’s functions from Java: [24]. So my idea was to try and call a Matlab function inside the custom Java callback function. However, I’m not sure how to interact with the JDBC via Matlab besides the standard SQL queries. Any advice would be appreciated!

#4 Comment By Alexander Eder On January 30, 2023 @ 16:03

Unfortunately Matlab stopped shipping sqlite4java starting with R2021(b?)

#5 Comment By Yair Altman On February 5, 2023 @ 11:43

@Alexander – this is correct. Matlab stopped including sqlite4java in R2021b (it was still included in 21a). You can download the open-source sqlite4java project from [21] or [25]
Note that sqlite4java is not actively maintained: the last commit was in 2019, and the downloaded binaries use a rather outdated version of the sqlite database (3.8.7).

When using sqlite in Matlab I usually prefer using the mksqlite utility ( [10]), which is actively maintained and works [extremely well] with the latest sqlite versions.


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/using-sqlite-in-matlab

URLs in this post:

[1] SQLite database: http://sqlite.org

[2] ALM Works: http://almworks.com

[3] the project repository: https://bitbucket.org/almworks/sqlite4java

[4] exposed: http://poquitopicante.blogspot.co.il/2015/03/sqlite-in-matlab.html

[5] JDBC: http://www.oracle.com/technetwork/java/javase/jdbc/index.html

[6] sqlite-jdbc: https://bitbucket.org/xerial/sqlite-jdbc

[7] sqlitejdbc: https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/sqlitebot/sqlitejdbc-v056.jar

[8] integral SQLite connector: https://www.mathworks.com/help/database/ug/working-with-the-matlab-interface-to-sqlite.html

[9] short discussion here: https://gist.github.com/cbcunc/e2bc3ef170544e4bf0f0

[10] mksqlite connector: http://mksqlite.sourceforge.net

[11] Martin Kortmann: http://www.kortmann.de

[12] Andreas Martin: https://github.com/AndreasMartin72

[13] .NET-based connector: http://www.codingtricks.biz/working-with-sqlite-database-in-matlab/

[14] Python one: https://www.pythoncentral.io/introduction-to-sqlite-in-python/

[15] Secure SSL connection between Matlab and PostgreSQL : https://undocumentedmatlab.com/articles/secure-ssl-connection-between-matlab-and-postgresql

[16] Speeding up Matlab-JDBC SQL queries : https://undocumentedmatlab.com/articles/speeding-up-matlab-jdbc-sql-queries

[17] Matlab toolstrip – part 5 (icons) : https://undocumentedmatlab.com/articles/matlab-toolstrip-part-5-icons

[18] Sending HTML emails from Matlab : https://undocumentedmatlab.com/articles/sending-html-emails-from-matlab

[19] Types of undocumented Matlab aspects : https://undocumentedmatlab.com/articles/types-of-undocumented-matlab-aspects

[20] Converting Java vectors to Matlab arrays : https://undocumentedmatlab.com/articles/converting-java-vectors-to-matlab-arrays

[21] : https://code.google.com/archive/p/sqlite4java

[22] : https://bitbucket.org/almworks/sqlite4java/issues

[23] : https://stackoverflow.com/questions/3192443/writing-user-defined-sql-functions-for-sqlite-using-java-or-groovy

[24] : https://www.mathworks.com/help/matlab/matlab_external/execute-matlab-functions-from-java.html

[25] : https://bitbucket.org/almworks/sqlite4java/src

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.