Using your own custom data types¶
You can make your own data types by subclassing Table (or other PyTables types,
such as tables.Leaf
).
This can be useful for storing a specialized type of data or presenting a
customized API.
Submitted by Kevin R. Thornton.
import numpy as np
import tables
from tables import File, Table
from tables.file import _checkfilters
from tables.parameters import EXPECTED_ROWS_TABLE
class DerivedFromTable(Table):
_c_classId = 'DerivedFromTable'
def __init__(self, parentNode, name, description=None,
title="", filters=None,
expectedrows=EXPECTED_ROWS_TABLE,
chunkshape=None, byteorder=None, _log=True):
super().__init__(parentNode, name,
description=description, title=title,
filters=filters,
expectedrows=expectedrows,
chunkshape=chunkshape, byteorder=byteorder,
_log=_log)
def read(self, start=None, stop=None, step=None, field=None):
print("HERE!")
data = Table.read(self, start=start, stop=stop, step=step,
field=field)
return data
def createDerivedFromTable(self, where, name, data, title="",
filters=None, expectedrows=10000,
chunkshape=None, byteorder=None,
createparents=False):
parentNode = self._get_or_create_path(where, createparents)
_checkfilters(filters)
return DerivedFromTable(parentNode, name, data,
title=title, filters=filters,
expectedrows=expectedrows,
chunkshape=chunkshape, byteorder=byteorder)
File.createDerivedFromTable = createDerivedFromTable
if __name__ == '__main__':
x = np.random.rand(100).reshape(50,2)
x.dtype = [('x',float), ('y',float)]
h5file = tables.open_file('tester.hdf5', 'w')
mtab = h5file.createDerivedFromTable(h5file.root, 'random', x)
h5file.flush()
print(type(mtab))
mtab_read = mtab.read()
h5file.close()
h5file = tables.open_file('tester.hdf5', 'r')
mtab = h5file.root.random
print(type(mtab))
mtab_read2 = mtab.read()
print(np.array_equal(mtab_read, mtab_read2))
There is an issue that the DerivedFromTable read function will not be called when the file is re-opened. The notion that the H5 file contains a derived object gets lost. The output shows that the read function is only called before the function is closed:
- ::
<class ‘__main__.DerivedFromTable’> HERE! <class ‘tables.table.Table’> True Closing remaining open files:tester.hdf5…done
I ran into this because I wanted a custom read that returned a more complex object implemented in C++. Using pybind11, I’m easily able to write to a Table via a record array. I was hoping that I could read back in, construct the correct C++-based type, and return it. The example seems to suggest that this is not possible.