5

外部プロセスによって生成されたデータを、sqlalchemy を使用して postgres データベースに格納する作業を行っています。外部データにはいくつかの日付が文字列として保存されており、比較と期間の計算のために日時オブジェクトとして使用したいと考えており、一貫性を維持するためにデータ モデルで変換を行いたいと考えています。Hybrid_property を使用しようとしていますが、SQLAlchemy が Hybrid_property をインスタンスまたはクラスとして使用するさまざまな方法に基づいて問題が発生しています。

(簡略化された)ケースは次のようになります...

class Contact(Base):
    id = Column(String(100), primary_key=True)
    status_date = Column(String(100))

    @hybrid_property
    def real_status_date(self):
        return convert_from_outside_date(self.status_date)

このような変換関数を使用すると (関数は日付を返し、変換が失敗した場合は False、None が渡された場合は None を返すことができます)...

def convert_from_outside_date(in_str):
    out_date = None

    if in_str != None:
        try:
            out_date = datetime.datetime.strptime(in_str,"%Y-%m-%d")
        except ValueError:
            out_date = False
    return out_date

Contact のインスタンスを使用すると、contact.real_status_date が適切に日時として機能します。問題は、Contact.real_status_date がクエリ フィルターで使用されている場合です。

db_session.query(Contact).filter(
    Contact.real_status_date > datetime.datetime.now())

「TypeError: この句のブール値が定義されていません」という例外を取得します。

in_str != None

スタック トレースの最後の部分として変換関数の行。

いくつかの回答 ( https://stackoverflow.com/a/14504695/416308 ) は、セッター関数の使用とデータ モデルへの新しい列の追加を示しています。他の回答 ( https://stackoverflow.com/a/13642708/416308 ) は、sqlalchemy が sql 式に解釈できるものを返す @property.expression 関数の追加を示しています。

Contact クラスへのセッターの追加は機能しますが、新しい列の追加は必要ないように思われ、後で一部のテーブル メタデータの解析がより困難になるため、できれば避けたいと思います。

_real_status_date = Column(DateTime())

@hybrid_property
def real_status_date(self):
    return self._real_status_date

@real_status_date.setter
def value(self):
    self._real_status_date = convert_from_outside_date(self.status_date)

@.expression デコレーターを使用した場合、より SQL と互換性のある strptime 関数を実装する必要がありますか? それはどのように見えるでしょうか?ここで問題を引き起こしている変換関数に何か問題がありますか?

4

1 に答える 1

0

zzzeek言及しているように、クラスに以下を追加できます

DB によっては、既に Pythondatetimeオブジェクトを解釈している場合があります。

したがって、変換関数を次のように変更するだけで機能します。

def convert_from_outside_date(in_str):
if in_str:
    try:
        return datetime.datetime.strptime(in_str,"%Y-%m-%d")
# Return None for a Null date
return None

それ以外の場合は、式関数を追加する必要があります:

@real_status_date.expression
def real_status_date(self):
    return sqlalchemy.Date(self.real_status_date)
于 2014-02-19T03:16:56.617 に答える