2009-04-18 4 views
3

Hintergrund gibt es mehrere Möglichkeiten, Daten in MySQ zu speichern.Definieren einer Tabelle mit sqlalchemy mit einem Mysql-Unix-Timestamp

  1. Als Zeichenfolge z. "09/09/2009".
  2. Als Integer mit der Funktion UNIX_TIMESTAMP() ist dies vermutlich die traditionelle Unix-Zeitdarstellung (Sie kennen Sekunden seit der Epoche plus/minus Schaltsekunden).
  3. Als MySQL TIMESTAMP ist ein mysql-spezifischer Datentyp nicht identisch mit Unix-Zeitstempeln.
  4. Als ein MySQL-Datum-Feld, ein anderer mysql-spezifischer Datentyp.

    Es ist sehr wichtig, Fall 2 nicht mit Fall 3 (oder Fall 4) zu verwechseln. Ich habe eine vorhandene Tabelle mit einem Ganzzahl-Datumsfeld (Fall 2) Wie kann ich es in sqlalchemy auf eine Weise definieren, die ich nicht mysql "FROM_UNIXTIME" -Funktion zugreifen muss?

    Für die Aufzeichnung, nur mit sqlalchemy.types.DateTime und in der Hoffnung, es tut das Richtige, wenn es eine Integer-Spalte nicht funktioniert, funktioniert es für Timestamp Felder und Datumsfelder.

Antwort

6

Ich denke, es gibt ein paar Probleme mit dem Typ Dekorateur Sie gezeigt haben.

  1. impl sollte sqlalchemy.types.Integer statt DateTime sein.
  2. Der Decorator sollte NULL-fähige Spalten zulassen.

Hier ist das, was ich im Sinn haben:


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

Ok ich es mag, schade das es nicht am Ende der Produktion gemacht hat. Aber warum hast du den Motor durch _ ersetzt? – rgz

+0

Nur eine Angewohnheit. pylint mag nicht verwendete Variablen, daher verwenden wir per Konvention _. –

2

Also ja, dieser Ansatz funktioniert. Und am Ende habe ich meine eigene Frage beantwortet: /, hoffe jemand findet das nützlich.

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)