如何在游标上覆盖psycopg2 tzinfo_factory

时间:2017-05-03 16:18:41

标签: python python-3.x psycopg2

因为[原因],我正在考虑覆盖由pyscopg2设置的tzinfo类。我想到这将是覆盖tzinfo_factorycursor的简单案例。但是,这似乎不起作用。

import psycopg2
from psycopg2.extensions import cursor
from psycopg2.tz import FixedOffsetTimezone

class MyFixedOffsetTimezone(FixedOffsetTimezone):
    pass

class MyCursorFactory(cursor):
    tzinfo_factory = MyFixedOffsetTimezone
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

conn = psycopg2.connect('', cursor_factory=MyCursorFactory)
cursor = conn.cursor()
cursor.execute("select now()")
results = cursor.fetchall()
print(results[0][0].tzinfo)
print(results[0][0].tzinfo.__class__)

仍然会给你

$ python3 example.py 
psycopg2.tz.FixedOffsetTimezone(offset=60, name=None)
<class 'psycopg2.tz.FixedOffsetTimezone'>

这是我对C实现的成员和更高级别的python如何交互的基本误解的结果吗? (或者我是一个完整的pleb?)版本:python 3.5.2在psycopg2 2.6.22.7.1

中进行了测试

我已经浏览了代码,它确实在光标上引用tzinfo_factory(psycopg / typecast_datetime.c:typecast_PYDATETIME_cast line 140 @ 2.7.1)

tzinfo_factory = ((cursorObject *)curs)->tzinfo_factory;

1 个答案:

答案 0 :(得分:1)

您必须传递cursor_factory=...并将MyFixedOffsetTimezone分配给MyCursorFactory:

class MyFixedOffsetTimezone(FixedOffsetTimezone):
    pass

class MyCursorFactory(cursor):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.tzinfo_factory = MyFixedOffsetTimezone

conn = psycopg2.connect('...')
cursor = conn.cursor(cursor_factory=MyCursorFactory)
cursor.execute("select now()")
results = cursor.fetchall()
print(results[0][0].tzinfo)
print(results[0][0].tzinfo.__class__)

返回:

psycopg2.tz.FixedOffsetTimezone(offset=120, name=None)
<class '__main__.MyFixedOffsetTimezone'>