@@ -90,7 +90,6 @@ def _tables():
90
90
91
91
return _table_mod
92
92
93
-
94
93
@contextmanager
95
94
def get_store (path , mode = 'a' , complevel = None , complib = None ,
96
95
fletcher32 = False ):
@@ -197,6 +196,11 @@ def __init__(self, path, mode='a', complevel=None, complib=None,
197
196
self .filters = None
198
197
self .open (mode = mode , warn = False )
199
198
199
+ @property
200
+ def root (self ):
201
+ """ return the root node """
202
+ return self .handle .root
203
+
200
204
def __getitem__ (self , key ):
201
205
return self .get (key )
202
206
@@ -207,26 +211,32 @@ def __delitem__(self, key):
207
211
return self .remove (key )
208
212
209
213
def __contains__ (self , key ):
210
- return hasattr (self .handle . root , key )
214
+ return hasattr (self .root , key )
211
215
212
216
def __len__ (self ):
213
- return len (self .handle . root . _v_children )
217
+ return len (self .groups () )
214
218
215
219
def __repr__ (self ):
216
220
output = '%s\n File path: %s\n ' % (type (self ), self .path )
217
221
218
- if len (self ) > 0 :
219
- keys = []
222
+ groups = self .groups ()
223
+ if len (groups ) > 0 :
224
+ keys = []
220
225
values = []
221
- for k , v in sorted (self . handle . root . _v_children . iteritems () ):
222
- kind = getattr (v ._v_attrs ,'pandas_type' ,None )
226
+ for n in sorted (groups , key = lambda x : x . _v_name ):
227
+ kind = getattr (n ._v_attrs ,'pandas_type' ,None )
223
228
224
- keys .append (str (k ))
229
+ keys .append (str (n . _v_pathname ))
225
230
231
+ # a group
226
232
if kind is None :
227
- values .append ('unknown type' )
233
+ values .append ('' )
234
+
235
+ # a table
228
236
elif _is_table_type (v ):
229
- values .append (str (create_table (self , v )))
237
+ values .append (str (create_table (self , n )))
238
+
239
+ # another type of pandas object
230
240
else :
231
241
values .append (_NAME_MAP [kind ])
232
242
@@ -241,7 +251,7 @@ def keys(self):
241
251
Return a (potentially unordered) list of the keys corresponding to the
242
252
objects stored in the HDFStore
243
253
"""
244
- return self .handle . root . _v_children . keys ()
254
+ return [ n . _v_pathname [ 1 :] for n in self .groups () ]
245
255
246
256
def open (self , mode = 'a' , warn = True ):
247
257
"""
@@ -304,12 +314,10 @@ def get(self, key):
304
314
-------
305
315
obj : type of object stored in file
306
316
"""
307
- exc_type = _tables ().NoSuchNodeError
308
- try :
309
- group = getattr (self .handle .root , key )
310
- return self ._read_group (group )
311
- except (exc_type , AttributeError ):
317
+ group = self .get_node (key )
318
+ if group is None :
312
319
raise KeyError ('No object named %s in the file' % key )
320
+ return self ._read_group (group )
313
321
314
322
def select (self , key , where = None ):
315
323
"""
@@ -322,11 +330,12 @@ def select(self, key, where=None):
322
330
where : list of Term (or convertable) objects, optional
323
331
324
332
"""
325
- group = getattr (self .handle .root , key , None )
333
+ group = self .get_node (key )
334
+ if group is None :
335
+ raise KeyError ('No object named %s in the file' % key )
326
336
if where is not None and not _is_table_type (group ):
327
337
raise Exception ('can only select with where on objects written as tables' )
328
- if group is not None :
329
- return self ._read_group (group , where )
338
+ return self ._read_group (group , where )
330
339
331
340
def put (self , key , value , table = False , append = False ,
332
341
compression = None , ** kwargs ):
@@ -352,9 +361,6 @@ def put(self, key, value, table=False, append=False,
352
361
self ._write_to_group (key , value , table = table , append = append ,
353
362
comp = compression , ** kwargs )
354
363
355
- def _get_handler (self , op , kind ):
356
- return getattr (self , '_%s_%s' % (op , kind ))
357
-
358
364
def remove (self , key , where = None ):
359
365
"""
360
366
Remove pandas object partially by specifying the where condition
@@ -372,15 +378,21 @@ def remove(self, key, where=None):
372
378
number of rows removed (or None if not a Table)
373
379
374
380
"""
375
- if where is None :
376
- self .handle .removeNode (self .handle .root , key , recursive = True )
377
- else :
378
- group = getattr (self .handle .root , key , None )
379
- if group is not None :
381
+ group = self .get_node (key )
382
+ if group is not None :
383
+
384
+ # remove the node
385
+ if where is None :
386
+ group = self .get_node (key )
387
+ group ._f_remove (recursive = True )
388
+
389
+ # delete from the table
390
+ else :
380
391
if not _is_table_type (group ):
381
392
raise Exception ('can only remove with where on objects written as tables' )
382
393
t = create_table (self , group )
383
394
return t .delete (where )
395
+
384
396
return None
385
397
386
398
def append (self , key , value , ** kwargs ):
@@ -416,20 +428,52 @@ def create_table_index(self, key, **kwargs):
416
428
if not _table_supports_index :
417
429
raise ("PyTables >= 2.3 is required for table indexing" )
418
430
419
- group = getattr ( self .handle . root , key , None )
431
+ group = self .get_node ( key )
420
432
if group is None : return
421
433
422
434
if not _is_table_type (group ):
423
435
raise Exception ("cannot create table index on a non-table" )
424
436
create_table (self , group ).create_index (** kwargs )
425
437
438
+ def groups (self ):
439
+ """ return a list of all the groups (that are not themselves a pandas storage object) """
440
+ return [ g for g in self .handle .walkGroups () if getattr (g ._v_attrs ,'pandas_type' ,None ) ]
441
+
442
+ def get_node (self , key ):
443
+ """ return the node with the key or None if it does not exist """
444
+ try :
445
+ if not key .startswith ('/' ):
446
+ key = '/' + key
447
+ return self .handle .getNode (self .root ,key )
448
+ except :
449
+ return None
450
+
451
+ ###### private methods ######
452
+
453
+ def _get_handler (self , op , kind ):
454
+ return getattr (self , '_%s_%s' % (op , kind ))
455
+
426
456
def _write_to_group (self , key , value , table = False , append = False ,
427
457
comp = None , ** kwargs ):
428
- root = self .handle .root
429
- if key not in root ._v_children :
430
- group = self .handle .createGroup (root , key )
431
- else :
432
- group = getattr (root , key )
458
+ group = self .get_node (key )
459
+ if group is None :
460
+ paths = key .split ('/' )
461
+
462
+ # recursively create the groups
463
+ path = '/'
464
+ if len (paths ) > 1 :
465
+ for p in paths [:- 1 ]:
466
+ new_path = path
467
+ if not path .endswith ('/' ):
468
+ new_path += '/'
469
+ new_path += p
470
+ group = self .get_node (new_path )
471
+ if group is None :
472
+ group = self .handle .createGroup (path , p )
473
+ path = new_path
474
+
475
+ # create the required group
476
+ group = self .handle .createGroup (path , paths [- 1 ])
433
477
434
478
kind = _TYPE_MAP [type (value )]
435
479
if table or (append and _is_table_type (group )):
0 commit comments