'''Alternate DB based on a dict subclass Runs like gdbm's fast mode (all writes all delayed until close). While open, the whole dict is kept in memory. Start-up and close time's are potentially long because the whole dict must be read or written to disk. File format is selectable between pickle, json, eval, and csv. All three are backed by fast C implementations. ''' import os, pickle, json, csv class DictDB(dict): def __init__(self, filename, flag='c', mode=None, format='csv', *args, **kwds): # r=readonly c=read_write_create_if_needed n=new_overwrite_previous self.flag = flag self.mode = mode self.format = format self.filename = filename if flag != 'n' and os.access(filename, os.R_OK): file = __builtins__.open(filename, 'rb') try: self.update(self.load(file)) finally: file.close() self.update(*args, **kwds) def sync(self): if self.flag != 'r': file = __builtins__.open(self.filename, 'wb') try: self.dump(file) finally: file.close() if self.mode: os.chmod(self.filename, self.mode) def close(self): self.sync() def dump(self, f): if self.format == 'csv': csv.writer(f).writerows(self.iteritems()) elif self.format == 'json': json.dump(self, f, separators=(',',':')) elif self.format == 'pickle': pickle.dump(self.items(), f, -1) elif self.format == 'eval': f.write(repr(self)) else: raise NotImplementedError('Unknown format: %r' % self.format) def load(self, f): # Use csv or json for untrusted data. Handles only basic types. # Use pickle or eval only for trusted. Handles many object types. if self.format == 'csv': return csv.reader(f) elif self.format == 'json': return json.load(f) elif self.format == 'pickle': return pickle.load(f) elif self.format == 'eval': return eval(f.read()) else: raise NotImplementedError('Unknown format: %r' % self.format) def myopen(filename, flag='c', mode=0o666, format='csv'): return DictDB(filename, flag, mode, format) if __name__ == '__main__': os.chdir('/dbm_sqlite/alt') print(os.getcwd()) s = myopen('tmp.shl', 'c', format='json') print(s, 'start') s['xyz'] = 'pdq' s['abc'] = '123' s.close() f = __builtins__.open('tmp.shl', 'rb') print (f.read()) f.close()