SQLAlchemy DateTime 对象只能是幼稚的吗? [英] Can SQLAlchemy DateTime Objects Only Be Naive?

查看:22
本文介绍了SQLAlchemy DateTime 对象只能是幼稚的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 SQLAlchemy,但我不确定我将在它下使用哪个数据库,因此我希望尽可能保持与数据库无关.如何在不将自己绑定到特定数据库的情况下在数据库中存储时区感知日期时间对象?现在,我在将时间存储在数据库中之前确保时间是 UTC,并在显示时转换为本地化,但这感觉既不优雅又脆弱.是否有一种与数据库无关的方法可以从 SQLAlchemy 中获取时区感知的日期时间,而不是从数据库中获取原始数据时间对象?

I am working with SQLAlchemy, and I'm not yet sure which database I'll use under it, so I want to remain as DB-agnostic as possible. How can I store a timezone-aware datetime object in the DB without tying myself to a specific database? Right now, I'm making sure that times are UTC before I store them in the DB, and converting to localized at display-time, but that feels inelegant and brittle. Is there a DB-agnostic way to get a timezone-aware datetime out of SQLAlchemy instead of getting naive datatime objects out of the DB?

推荐答案

DateTime 列时间,所以存储时区感知datetime 对象.但是我发现使用简单类型装饰器自动将存储的 datetime 转换为 UTC 很方便:

There is a timezone parameter to DateTime column time, so there is no problem with storing timezone-aware datetime objects. However I found convenient to convert stored datetime to UTC automatically with simple type decorator:

from sqlalchemy import types
from datetime import datetime, timezone

class UTCDateTime(types.TypeDecorator):

    impl = types.DateTime

    def process_bind_param(self, value, engine):
        if value is None:
            return
        if value.utcoffset() is None:
            raise ValueError(
                'Got naive datetime while timezone-aware is expected'
            )
        return value.astimezone(timezone.utc)

    def process_result_value(self, value, engine):
        if value is not None:
            return value.replace(tzinfo=timezone.utc)

请注意,当您不小心使用朴素的 datetime 时,这会表现得很好(这意味着它会引发 ValueError).

Note, that is behaves nicely when you use naive datetime by accident (meaning it will raise a ValueError).

这篇关于SQLAlchemy DateTime 对象只能是幼稚的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆