转载注明出处 http://blog.youkuaiyun.com/xugangjava/article/details/7565321
由于项目中需要用到adodbapi,看过一些orm感觉和twisted的 PB兼容性都不是很好,
主要问题是,PB的 Jelly模块无法解析orm内部的一些类型,只有自己造轮子,写个简易的ORM,来简化代码
(最近时间比较紧,有不对的地方欢迎大家拍砖)
1.adodbapi查询出来对象格式化成对象,python可以根据字典来 初始化自身的属性
所以我们的Row对象
#data row
class Row(pb.Copyable):
def __init__(self,entries):
self.__dict__.update(entries)
在写个跟dataset类似的东西,如下
class ResultObj(pb.Copyable):
#字符串太长pb无法 传输,转成列表,原理跟FilePager一样
def __init__(self,rs,PageNo=1,pageSize=300,filedDict=None):
self.pageSize=pageSize
if rs.RecordCount:
rs.AbsolutePage=PageNo
self.pageNo=PageNo
rs.PageSize=self.pageSize
self.pageCount=rs.PageCount
if rs.RecordCount:
self.rs=rs.GetRows(self.pageSize)
self.field_num=rs.Fields.Count
self.next=None
self.count=self.pageSize
if self.pageNo<self.pageCount:
self.next=ResultObj(rs,PageNo+1,self.pageSize,filedDict)
else:
self.count=rs.RecordCount-(self.pageNo-1)*self.pageSize
#查询结果的每一列 生成字典
if filedDict is None:
self.filedDict={}
for n in xrange(self.field_num):
self.filedDict[n]=rs.Fields.Item(n).Name.lower()
#没有列明转成 c0 c1.....
if not self.filedDict[n]:
self.filedDict[n]='c'+str(n)
else:
self.filedDict=filedDict
def __len__(self):
return self.count
def __getitem__(self,key):
row={}
for cur_col in xrange(self.field_num):
row[self.filedDict[cur_col]]=self.rs[cur_col][key]
return Row(row)
def __iter__(self):
return iter(self.__next__())
#遍历列表
def __next__(self):
fiedlcount=xrange(self.field_num)
while self:
for cur_row in xrange(self.count):
row={}
for cur_col in fiedlcount:
row[self.filedDict[cur_col]]=self.rs[cur_col][cur_row]
yield Row(row)
self=self.next
OK我们来查询对象了
def queryObj(conn,sql,*args):
cur=conn.cursor()
cur.execute(sql,args)
return ResultObj(cur.rs)
这样我们现在可以这样来查询对象了,在下一篇文章中,将使用 下面第二行的函数来进一步简化我们的SQL
#1.
print queryObj(conn,'select username from users where uid=1').username
#输出 admin
#2.
print select(conn,'username','Users',uid=1)[0].username