我必须将一些数据从各种数据库(目前是 Oracle 和 Postgre)转储到 CSV 文件中,同时保留列类型信息,以便可以将数据正确加载到另一个应用程序中。基本上,我需要编写一个函数,该函数可以以独立于所使用的特定 DBAPI 模块的方式将列数据中的字符串/数字数据与游标对象区分开来。
根据DB-API v2 文档,每个 DBAPI 模块必须定义类型对象(例如module.STRING
),这些对象“必须比较等于”每列(例如cursor.description[n][1]
,对于第 n 列)的游标对象中的类型对象。
我遇到的问题是......如果我只能访问游标对象,我怎么能找出适合这个比较的类型对象是什么?如何从游标对象中获取相应 DBAPI 模块的句柄。有什么意见或建议吗?
到目前为止,我一直在使用丑陋的 kludge:
def FigureOutDBTypes(cursor):
if 'psycopg2' in str(type(cursor)):
coltypes = [(str if x[1]==1043 else int) for x in cursor.description]
elif 'Oracle' in str(type(cursor)):
typemap = dict(NUMBER = int,
DATE = int,
DATETIME = int,
TIMESTAMP = int,
STRING = str)
coltypes = [typemap.get(x[1] and x[1].__name__, int) for x in cursor.description]
else:
raise RuntimeError("Don't know how to get type information from DB cursor.", cursor)
return coltypes
我想要一个更强大和优雅的解决方案。有什么意见或建议吗?
编辑:到目前为止我想出的最好的事情是使用以下几乎一样可怕的黑客来处理适当的模块:
mod = sys.modules[cur.connection.__class__.__module__] #FIXME!
coltypes = [(str if x[1]==mod.STRING else int) for x in cursor.description]