2

私は sqlalchemy で相対的な日付範囲 (月、年) の基本的なサポートを実装しようとしています。データベースとしてpostgresを使用して、sqlalchemy.dialects.postgres.Intervalをサブクラス化し、返されたpythonタイプをdateutil.relativedelta.relativedeltaに変更することが最善/最速の方法だと思いました。

from sqlalchemy import types
from sqlalchemy.dialects.postgres import INTERVAL
from dateutil import relativedelta

class DateInterval(INTERVAL):
    def result_processor(self, dialect, coltype):
        def process(value):
            return value
        return process

@property
def python_type(self):
    return relativedelta.relativedelta


class MyInterval(types.TypeDecorator):
    impl = DateInterval

    def process_bind_param(self, value, dialect):
        result = ''
        for attr in ["years", "months", "days", "hours", "minutes", "seconds"]:
            tempvalue = getattr(value, attr)
            if tempvalue:
                result += "%s %s " % (tempvalue, attr)
        return result

    def process_result_value(self, value, engine):
        return value

    @property
    def python_type(self):
        return relativedelta.relativedelta

db へのフラッシュは期待どおりに機能し、process_bind_param メソッドは機能します。後で取得しても、そうではありません。result_processor メソッドのプロセス関数の値引数は、既に timedelta オブジェクトです。生の値をrelativedeltaオブジェクトに処理するために、どこにフックするのですか? それとももっと良い方法がありますか?

4

1 に答える 1

1

psycopg2 はそれらのタイムデルタを返しています。それらを傍受したい場合は、psycopg2 レベルで拡張する必要があります: http://initd.org/psycopg/docs/advanced.html#type-casting-of-sql-types-into-python-objects おそらく、new_type() を使用して、区間オブジェクトの psycopg2 のデフォルトの型コンバーターを回避できます。

ステップ1は、プレーンなpsycopg2接続/カーソルから生の値を取得して、そのレベルで制御できるようにすることです。

それを取得する方法を理解したら、新しく作成された psycopg2 接続オブジェクトをインターセプトし、接続イベント内で必要なアダプターをセットアップできます。

于 2013-10-10T18:49:58.847 に答える