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))
自己