ORM for pys60
Here's my own first version for an ORM.
It's adapted from SQLAlchemy and SQLObject.
(and whatever library I have searched)
You need to create a database manually first.
My previous snippets (shell, SQL) may help.
1 2 from __future__ import generators 3 import e32db, re 4 db = e32db.Dbms() 5 dbv = e32db.Db_view() 6 db.open(u'C:\\test.db') 7 8 # Some helping classes (need more in next version) 9 class String: 10 pass 11 12 class Integer: 13 pass 14 15 class Float: 16 pass 17 18 class column: 19 def __init__(self, coltype): 20 self.coltype = coltype
Here's the mother of all your classes that map to database tables.
1 2 class Mapper(object): 3 def __init__(self, id=None, **kw): 4 if id is None: 5 self.id = self._insert(**kw) 6 else: 7 self.id = id 8 def _insert(self, **kw): 9 names = ','.join(kw.keys()) 10 values = ','.join([self.quote(k,v) for k,v in kw.items()]) 11 tablename = self.__class__.__name__ 12 q = u"INSERT INTO %s(%s) VALUES (%s)" % (tablename, names, values) 13 db.execute(q) 14 # get last insert ID 15 dbv.prepare(db, u'SELECT id FROM '+tablename+' ORDER BY id DESC') 16 dbv.first_line() 17 dbv.get_line() 18 return dbv.col(1) 19 def __getattr__(self, name): 20 if name in self.mapping.__dict__: 21 q = 'SELECT '+name+' FROM '+self.__class__.__name__ 22 q += ' WHERE id='+str(self.id) 23 dbv.prepare(db, unicode(q)) 24 dbv.first_line() 25 dbv.get_line() 26 return dbv.col(1) 27 else: 28 return self.__dict__[name] 29 def __repr__(self): 30 return '<%s id=%d>' % (self.__class__.__name__, self.id) 31 def quote(self, name, value): 32 if self.mapping.__dict__[name].coltype == String: 33 return "'%s'" % value.replace("'", "''") # encode single quote 34 else: 35 return str(value) 36 def __setattr__(self, name, value): 37 if name in self.mapping.__dict__: 38 q = 'UPDATE '+self.__class__.__name__+' SET '+name+'=' 39 q += self.quote(name, value) + " WHERE id=" + str(self.id) 40 db.execute(unicode(q)) 41 else: 42 self.__dict__[name] = value 43 def set(self, **kw): 44 q = "UPDATE "+self.__class__.__name__+" SET " 45 for k, v in kw.items(): 46 q += k+'='+self.quote(k,v)+',' 47 q = q[:-1]+" WHERE id=%s" % self.id 48 db.execute(unicode(q)) 49 def delete(self): 50 q = 'DELETE FROM '+self.__class__.__name__+" WHERE id=" + str(self.id) 51 db.execute(unicode(q)) 52 self.id = None 53 def dict(self): 54 names = [k for k in self.mapping.__dict__.keys() if not k.startswith('__')] 55 q = 'SELECT '+','.join(names)+' FROM '+self.__class__.__name__ 56 q += ' WHERE id=' + str(self.id) 57 dbv.prepare(db, unicode(q)) 58 dbv.first_line() 59 dbv.get_line() 60 dct = {'id': self.id} 61 for i in range(dbv.col_count()): 62 dct[names[i]] = dbv.col(i+1) 63 return dct 64 def select(cls, where=None, orderby=None): 65 q = 'SELECT id FROM '+cls.__name__ 66 if where: 67 q += ' WHERE '+where 68 if orderby: 69 q += ' ORDER BY '+orderby 70 dbv = e32db.Db_view() # need its own cursor 71 dbv.prepare(db, unicode(q)) 72 dbv.first_line() 73 for i in range(dbv.count_line()): 74 dbv.get_line() 75 yield cls(dbv.col(1)) 76 dbv.next_line() 77 select = classmethod(select)
Here's how you create your class.
1 2 class Person(Mapper): 3 class mapping: 4 # doesn't need id = column(Integer) 5 name = column(String) 6 age = column(Integer)