On Wed, 2002-07-10 at 16:20, Lamar Owen wrote: > On Wednesday 10 July 2002 09:11 am, Hannu Krosing wrote: > > On Wed, 2002-07-10 at 01:09, Lamar Owen wrote: > > > The wc utility isn't in the path in an OS install situation. The df > > > utility isn't in the path, either. You can use python, though. :-) Not > > > that that would be a good thing in this context, however. > > > Why not ? > > > The following is wc in python > > [snip] > > > And I have written custom postgres table dumpers in python without too > > much effort (except reverse-engineering the page structure ;) for both > > 6.x and 7.x database tables, so we could actually use python here too. > > I'm willing to look into this. However, the dump still has to be pulled with > a standalone backend -- no networking availability can be assumed.
Actually it works on raw table file ;) I attach code that dumps data from page file for table of 4 ints all NOT NULL, like create table fourints( i1 int not null, i2 int not null, i3 int not null, i4 int not null ); the script is meant for quick and dirty resque operations, and requires that one writes their own data-field extractor code. I have used it mainly to resurrect accidentally deleted data. it is for 7.x style pagefile layout ------------------- Hannu
#!/usr/bin/python import sys,os,struct,string page_size = 8*1024 def strbits(s,len): bits = [] while s: c = s[0] s = s[1:] b = struct.unpack('B',c)[0] for i in range(8): if b & (1<<i): bits.append(1) else: bits.append(0) return string.join(map(str,bits),'')[:len] DEBUGPRINT = 0 class table_page: "class to represent a database table page" def __init__(self,fd,page_nr,dataconv): fd.seek(page_nr*page_size) self.rawdata = fd.read(page_size) if not self.rawdata: return self.lower,\ self.upper,\ self.special,\ self.opaque = \ struct.unpack('HHHH',self.rawdata[12:20]) self.item_pointers=[] self.items=[] if DEBUGPRINT: print self.lower,self.upper,self.special,self.opaque for i in range(20,self.lower,4): rawItemIdData = self.rawdata[i:i+4] ItemIdData_I32 = struct.unpack('L',rawItemIdData)[0] if not ItemIdData_I32: break lp_len = int(ItemIdData_I32 >> 17) lp_flags = int((ItemIdData_I32 >> 15) & 3) lp_off = int(ItemIdData_I32 & 0x7fff) self.item_pointers.append((hex(ItemIdData_I32),lp_off,lp_flags,lp_len)) rawItemData = self.rawdata[lp_off:lp_off+lp_len] t_oid,t_001,t_002,t_xmin,t_xmax,tid1,tid2,t_fcnt,t_xxx,t_doff = \ struct.unpack('6L3HB', rawItemData[ 0: 31]) t_ctid = (tid1,tid2) t_mask = strbits(rawItemData[31:t_doff],t_fcnt) raw_data = rawItemData[t_doff:] # unpack 4 ints t_data = dataconv(raw_data,t_mask) self.items.append((t_oid,t_001,t_002,t_xmin,t_xmax,t_ctid,t_fcnt,t_xxx,t_doff,t_mask,t_data)) def __str__(self): return string.join(map(repr,self.items),'\n') if __name__=="__main__": site_base = "." db_name = "" table_name = "171617.16k" db_path = os.path.join(site_base,db_name) table_path = os.path.join(db_path,table_name) print table_path # this custom data converter must be written for each table # or derived from reading system tables def extract4ints(data,nullmask): return struct.unpack('LLLL', data) print '# dumping %s' % table_path fd = open(table_name) page_nr = 0 while 1: page = table_page(fd,page_nr,extract4ints) if not page.rawdata: break print page page_nr = page_nr + 1 print 'processed %d pages' % page_nr
---------------------------(end of broadcast)--------------------------- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]