Python 在SQLAlchemy中,有没有一种方法可以象征性地创建一个列,而实际上创建两个列?

Python 在SQLAlchemy中,有没有一种方法可以象征性地创建一个列,而实际上创建两个列?,python,sqlalchemy,Python,Sqlalchemy,考虑以下代码: class Appointment(Base): scheduled_date_utc = Column(DateTime) # Naive UTC scheduled_date_timezone = Column(TimezoneType()) # TimezoneType is from sqlalchemy-utils @property def scheduled_date(self) -> da

考虑以下代码:

class Appointment(Base):
    scheduled_date_utc = Column(DateTime)               # Naive UTC 
    scheduled_date_timezone = Column(TimezoneType())    # TimezoneType is from sqlalchemy-utils

    @property
    def scheduled_date(self) -> datetime:
        ... (assembles scheduled_date_utc and
             scheduled_date_timezone into a unified object)

    @scheduled_date.setter
    def scheduled_date(self, value: datetime):
        ... (splits up tz-aware datetime into naive UTC time,
             and timezone column, and sets them separately)
不要太担心属性方法,但要理解它们接受一个Python值,然后必须将该Python值拆分为两个数据库列

当然,我更喜欢创建自己的列类型:

class Appointment(Base):
    scheduled_date = Column(MyDatetimeAware())

问题是,
scheduled\u date
不仅仅是一列,还需要多列。有什么方法可以概括SQLAlchemy中的多列“数据类型”吗?

您正在考虑混合属性(请参阅)。这些可以用于在SQL和python设置中显示不同的行为,但也可以用于预定义某些转换。我经常使用它们将UTC时间戳转换为本地时区。请注意,属性定义了1-3次。一次是作为python属性,一次是关于SQL的运行方式,一次是关于setter

导入pytz 从sqlalchemy.ext.hybrid导入hybrid_属性 班级预约(基本): 计划的_日期_utc=列(日期时间)#原始utc scheduled_date_timezone=列(TimezoneType())#TimezoneType来自sqlalchemy utils @财产 def计划日期(自)->日期时间: #看https://stackoverflow.com/a/18646797/5015356 返回自计划日期utc\ .replace(tzinfo=pytz.utc)\ .astimezone(pytz.时区(自计划日期时区)) @计划日期.expr def计划日期(cls): 返回函数时区(cls.scheduled\u date\u时区,cls.scheduled\u date\u utc) 为了使解决方案可重用,您可以在
\uuuu setattr\uuuu
周围编写一个带有包装器的mixin:

导入pytz 类时区名称: def是时区感知属性(self,attr): 返回hasattr(self,attr+''u utc')和hasattr(self,attr+''u时区')) def _ugetattr _;(self,attr): """ __getattr__;只是作为最后的手段,如果没有其他手段的话 存在匹配列 """ 如果self.is\u timezone\u aware\u attr(attr): 返回函数时区(getattr(self,attr+“\u utc”), getattr(self,attr+“\u时区”)) raise AttributeError() 定义设置属性(自身、属性、值): 如果self.is\u timezone\u aware\u attr(attr): setattr(self,attr+'_utc',value.astimezone(tzinfo=pytz.utc)) setattr(self,attr+'_utc',value.tzinfo) raise AttributeError() 或者只使用一个共享的
时区
对象:

导入pytz 类时区名称: 时区=列(TimezoneType()) def是时区感知属性(self,attr): 返回hasattr(self,attr+'\u utc') def _ugetattr _;(self,attr): """ __getattr__;只是作为最后的手段,如果没有其他手段的话 存在匹配列 """ 如果self.is\u timezone\u aware\u attr(attr): 返回函数时区(getattr(self,attr+“\u utc”),self.timezone) raise AttributeError() 定义设置属性(自身、属性、值): 如果self.is\u timezone\u aware\u attr(attr): setattr(self,attr+'_utc',value.astimezone(tzinfo=pytz.utc)) self.timezone=value.tzinfo raise AttributeError()
您正在考虑的是
混合属性(请参阅)。这些可以用于在SQL和python设置中显示不同的行为,但也可以用于预定义某些转换。我经常使用它们将UTC时间戳转换为本地时区。请注意,属性定义了1-3次。一次是作为python属性,一次是关于SQL的运行方式,一次是关于setter

导入pytz 从sqlalchemy.ext.hybrid导入hybrid_属性 班级预约(基本): 计划的_日期_utc=列(日期时间)#原始utc scheduled_date_timezone=列(TimezoneType())#TimezoneType来自sqlalchemy utils @财产 def计划日期(自)->日期时间: #看https://stackoverflow.com/a/18646797/5015356 返回自计划日期utc\ .replace(tzinfo=pytz.utc)\ .astimezone(pytz.时区(自计划日期时区)) @计划日期.expr def计划日期(cls): 返回函数时区(cls.scheduled\u date\u时区,cls.scheduled\u date\u utc)
为了使解决方案可重用,您可以在
\uuuu setattr\uuuu
周围编写一个带有包装器的mixin:

导入pytz 类时区名称: def是时区感知属性(self,attr): 返回hasattr(self,attr+''u utc')和hasattr(self,attr+''u时区')) def _ugetattr _;(self,attr): """ __getattr__;只是作为最后的手段,如果没有其他手段的话 存在匹配列 """ 如果self.is\u timezone\u aware\u attr(attr): 返回函数时区(getattr(self,attr+“\u utc”), getattr(self,attr+“\u时区”)) raise AttributeError() 定义设置属性(自身、属性、值): 如果self.is\u timezone\u aware\u attr(attr): setattr(self,attr+'_utc',value.astimezone(tzinfo=pytz.utc)) setattr(self,attr+'_utc',value.tzinfo) raise AttributeError() 或者只使用一个共享的
时区
对象:

导入pytz 类时区名称: 时区=列(TimezoneType()) def是时区感知属性(self,attr): 返回hasattr(self,attr+'\u utc') def _ugetattr _;(self,attr): """ __getattr__;只是作为最后的手段,如果没有其他手段的话 存在匹配列 """ 如果self.is\u timezone\u aware\u attr(attr): 返回函数时区(getattr(self,attr+“\u utc”),self.timezone) raise AttributeError() 定义设置属性(自身、属性、值): 如果self.is\u timezone\u aware\u attr(attr): setattr(self,attr+'_utc',value.astimezone(tzinfo=pytz.utc)) 自己