故事是这样的。在
我有一堆存储过程,它们都有自己的参数类型。
我要做的是在python中创建一个类型安全层,这样我就可以在访问数据库之前确保所有值的类型都是正确的。在
当然,我不想再用python编写整个模式,所以我想我可以在启动时通过从数据库中获取参数名和类型来自动生成这些信息。在
所以我继续破解这个查询,只是为了测试
SELECT proname, proargnames, proargtypes
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p
ON pronamespace = n.oid
WHERE nspname = 'public';
然后我从python运行它,对于“proargtypes”,我为每个结果得到一个类似这样的字符串
^{pr2}$我敏锐的目光告诉我这些是postgresql类型的oid,用空格分隔,这个特定的字符串意味着函数接受varchar、integer、varchar。 所以在python中,这应该是
(unicode, int, unicode)
现在我如何从这些数字中得到python类型呢?在
理想的最终结果应该是这样
In [129]: get_python_type(23)
Out[129]: int
我找到了最接近的extensions.string_类型'但这只是将OID映射到sql类型名称。在
如果您想要Python类型的类,就像您可能从
SQLALchemy
列对象获得的那样,您需要构建和维护自己的映射。^{cd2>内部没有。在但是如果您想要的是从
oid
到一个将原始值转换为Python实例的函数,psycopg2.extensions.string_types
实际上已经是您需要的了。它看起来像是从oid
到一个名称的映射,但事实并非如此:它的值不是字符串,而是psycopg2._psycopg.type
的实例。是时候深入研究一些代码了。在psycopg2
公开了一个用于注册新类型转换器的API,我们可以使用它来追溯到与类型转换相关的C代码;这一点围绕中的typecastObject
展开 typecast.c,毫不奇怪,它映射到我们在老朋友string_types
中找到的{pcast
(对于Python casting函数)和{name
,这只是一个标签,values
,这是一个oid列表)。该类型向Python公开的是__call__
,事实证明,它只是在pcast
和{对光标的需求是不幸的,事实上,并不总是需要光标:
^{2}$但是转换实际字符串(
varchar
)类型的任何操作都依赖于PostgreSQL服务器的语言环境,至少在python3编译中是这样的,并且将None
传递给这些caster并不仅仅是失败,而是segfaults。您提到的方法cursor.cast(oid, raw)
,实际上是psycopg2.extensions.string_types
中caster的包装,在某些情况下可能更方便。在对于需要游标和连接的唯一解决方法,我能想到的是构建一个基本上是一个模拟连接对象。如果它在没有连接到实际数据库的情况下公开了所有相关的环境信息,那么它可以附加到一个cursor对象,并与}一起使用,但是mock将在C中构建并留给读者作为练习。在
string_types[oid](raw, cur)
或{postgres类型和python类型的映射是here。这有帮助吗?在
编辑: 从表中读取记录时,postgres(或任何数据库)驱动程序将自动将记录列类型映射到Python类型。在
现在,您只需在编写MySQL接口代码时将Python类型映射到MySQL类型。 但是,坦率地说,这是一种将类型从PostgreSQL类型映射到MySQL类型的迂回方式。我只引用这两个数据库之间的众多类型映射中的一个,比如this
相关问题 更多 >
编程相关推荐