Working with databases
DataMelt includes several database engines:
- Object-based database NeoDatis and jhplot.io.HDataBase
- SQLite database called SQLjet
- Apache Derby database (now comes with the JDK as JavaDB)
- HyperSQL database
jhplot.io.HDataBase allows to write and read data in a form of disk-based database using the keys. This is handy for non-sequential I/O. The class is based on the original code of D.Hamner (JavaWorld.com).
This raw-level database allows to store and retrieve objects. It associates a key of type String with each record. The keys will be limited to a maximum length, although the record data will not be limited. The record will consist of only one "blob" of binary data. The number of records is not fixed at creation time. The file can grow and shrink as records are inserted and removed. The database operations not depend on the number of records in the file. In other words, they'll be of constant order time with respect to file accesses. The index should be small enough to load into memory.
Here is a small example. We use two keys "0" and "1" (both are strings) and associate a string "Test" and 2D list with each key. Then we retrieve data from the file. In this approach, we use "persistent" database which keeps the data on the disk.
from jhplot.io import * file="output.db" f=HDataBase(file,"w") f.insert("0","Test") # store "Test" using the key "0" f.insert("1",[ [1,2,3,3],[2,3,4]]) # store 2D array using the key "1" f.close() f=HDataBase(file,"r") # open and retrieve data using the keys print f.get("0"),f.get("1")
The output of this code is shown below:
Test [[1, 2, 3, 3], [2, 3, 4]]
We can also write complicated objects "classes" into the files as in this example:
Here we sequentially write a complicated data structure "event" using several objects, and later retrieve it. This class allows only "string" type as the keys. We will show later how to use arbitrary types foe the keys.
Objects can be stored in HashMap which is kept in the memory. One can work with a huge amount of data using org.clapper.util.misc.FileHashMap which keeps the keys in memory, but stores the values as serialized objects in a random access disk file. This approach is very similar to the previous case, but the implementation is different.
In this example we create a file "/tmp/mytest" (in the temporary directory tmp) and put some data (1D,2D arrays and histogram):
from jhplot import * from org.clapper.util.misc import FileHashMap # make some massive java objects p1=P0D(); p1.randomNormal(10000,0,2) p2=P0D(); p2.randomNormal(10000,1,2) pp=P1D("test",p1,p2); h1=H1D("OK",100,0,10) ppp=PND(); ppp.add([1,2,3,4,5]); ppp.add([1,2,3,4,3]) ######### store all objects in the file print "Write to the database" map=FileHashMap("/tmp/mytest",FileHashMap.FORCE_OVERWRITE); map.put("d1",p1) map.put("d2",p2) map.put("d3",ppp) map.put("4",h1) print map.size() map.save() map.close() print "Closed database"
Note that the database will have 2 files: mytest.ix (index file) and mytest.db (actual data) Now we will read this database and extract stored objects. Then we print them:
from jhplot import * from org.clapper.util.misc import FileHashMap print "Read to the database" map=FileHashMap("/tmp/mytest",FileHashMap.RECLAIM_FILE_GAPS); p1=map.get("d1") p2=map.get("d2") ppp=map.get("d3") hh=map.get("4") print hh print ppp print map.size() map.close() print "Closed database"
A massive data can be stored a a map, where each key corresponds to some object (can be arbitrary Java objects). You can store collections backed up by disk storage and you can store and handle billions of data objects. Unlike the previous approach, we will consider the true database where you can rollback changes, encrypt the data, etc. As before, only serialize object can be stored. In this section we will show example of using this database. As before, no SQL is required and the key can have arbitrary types:
Below is an example in which we write many values using their keys, close the database, and read the values back from the database using their keys.
Note that the database creates several files in the /tmp/ directory (db,db.p).
Here is an example were we write 100 histograms into the database using integer keys, and then we read all histograms back.
Neodatis Object databases
DataMelt supports SQL-type of databases:
Below we will show Jython scripts how to work with such databases.
Starting from v3.8, Derby is excluded from the package since it comes with JDK as JavaDB (see the JAVAHOME/db/ directory). Here is example of how to write and read data using Derby: