我们(musicpictures.com/eviscape.com)写下了django代码段,但并不是全部内容(实际上,该代码当时仅在Oracle上进行了测试)。
当您要重用经过测试的SP代码时,或者在一个SP调用比对数据库的多次调用要快的情况下-或者在安全性要求对数据库进行适度访问的情况下-
或者在查询非常复杂/多步骤的情况下,存储过程才有意义。我们正在针对Oracle和Postgres数据库使用混合模型/ SP方法。
诀窍是使其易于使用并使其像“
django”一样。我们使用make_instance函数,该函数获取游标的结果并创建从游标填充的模型的实例。这很好,因为游标可能会返回其他字段。然后,您可以像普通的django模型对象一样在代码/模板中使用这些实例。
def make_instance(instance, values): ''' Copied from eviscape.com generates an instance for dict data coming from an sp expects: instance - empty instance of the model to generate values - dictionary from a stored procedure with keys that are named like the model's attributes use like: evis = InstanceGenerator(Evis(), evis_dict_from_SP) >>> make_instance(Evis(), {'evi_id': '007', 'evi_subject': 'J. Bond, Architect'}) <Evis: J. Bond, Architect> ''' attributes = filter(lambda x: not x.startswith('_'), instance.__dict__.keys()) for a in attributes: try: # field names from oracle sp are UPPER CASE # we want to put PIC_ID in pic_id etc. setattr(instance, a, values[a.upper()]) del values[a.upper()] except: pass #add any values that are not in the model as well for v in values.keys(): setattr(instance, v, values[v]) #print 'setting %s to %s' % (v, values[v]) return instance#像这样使用它:
pictures = [make_instance(Pictures(), item) for item in picture_dict]
#这是一些帮助函数:
def call_an_sp(self, var): cursor = connection.cursor() cursor.callproc("fn_sp_name", (var,)) return self.fn_generic(cursor)def fn_generic(self, cursor): msg = cursor.fetchone()[0] cursor.execute('FETCH ALL IN "%s"' % msg) thing = create_dict_from_cursor(cursor) cursor.close() return thingdef create_dict_from_cursor(cursor): rows = cursor.fetchall() # DEBUG settings (used to) affect what gets returned. if DEBUG: desc = [item[0] for item in cursor.cursor.description] else: desc = [item[0] for item in cursor.description] return [dict(zip(desc, item)) for item in rows]


