2009-04-18 44 views
3

背景下,有幾種方法可以在MySQ中存儲日期。使用mysql unix時間戳定義一個包含sqlalchemy的表格

  1. 作爲一個字符串,例如「09/09/2009」。
  2. 作爲使用函數UNIX_TIMESTAMP()的整數,這應該是傳統的unix時間表示(您知道自紀元加/減閏秒以來的秒數)。
  3. 作爲MySQL TIMESTAMP,mysql特定的數據類型與unix時間戳不同。
  4. 作爲MySQL日期字段,另一個mysql特定的數據類型。

    非常重要的是不要將案例2與案例3(或案例4)混淆。 我有一個整數日期字段(情況2)現有的表我怎麼可以在sqlalchemy中以我不必訪問mysql的「FROM_UNIXTIME」函數的方式定義它?

    爲了記錄,僅使用sqlalchemy.types.DateTime並希望它在檢測到整數列時執行正確的操作不起作用,它適用於時間戳字段和日期字段。

回答

6

我認爲你展示的類型裝飾器有幾個問題。

  1. impl應該sqlalchemy.types.Integer而不是DateTime
  2. 裝飾者應該允許空列。

這裏是我心目中是什麼:


import datetime, time 
from sqlalchemy.types import TypeDecorator, DateTime, Integer 

class IntegerDateTime(TypeDecorator): 
    """a type that decorates DateTime, converts to unix time on 
    the way in and to datetime.datetime objects on the way out.""" 
    impl = Integer # In schema, you want these datetimes to 
        # be stored as integers. 
    def process_bind_param(self, value, _): 
     """Assumes a datetime.datetime""" 
     if value is None: 
      return None # support nullability 
     elif isinstance(value, datetime.datetime): 
      return int(time.mktime(value.timetuple())) 
     raise ValueError("Can operate only on datetime values. " 
         "Offending value type: {0}".format(type(value).__name__)) 
    def process_result_value(self, value, _): 
     if value is not None: # support nullability 
      return datetime.datetime.fromtimestamp(float(value)) 
+0

好吧,我喜歡它,可惜這並沒有使其生產進行到底。但是你爲什麼用_替換引擎? – rgz 2009-05-30 08:31:13

2

所以是的,這種方法的工作原理。最後,我回答了自己的問題:/希望有人認爲這是有用的。

import datetime, time 
from sqlalchemy.types import TypeDecorator, DateTime 
class IntegerDateTime(TypeDecorator): 
    """a type that decorates DateTime, converts to unix time on 
    the way in and to datetime.datetime objects on the way out.""" 
    impl = DateTime 
    def process_bind_param(self, value, engine): 
     """Assumes a datetime.datetime""" 
     assert isinstance(value, datetime.datetime) 
     return int(time.mktime(value.timetuple())) 
    def process_result_value(self, value, engine): 
     return datetime.datetime.fromtimestamp(float(value)) 
    def copy(self): 
     return IntegerDateTime(timezone=self.timezone)