diff --git a/trytond/backend/fields.py b/trytond/backend/fields.py index c2efd8bc8e..1936905a99 100644 --- a/trytond/backend/fields.py +++ b/trytond/backend/fields.py @@ -98,7 +98,37 @@ class DateTime(Field): @staticmethod def sql_format(value): - return value or None + if not value: + return None + if isinstance(value, basestring): + datepart, timepart = value.split(" ") + year, month, day = map(int, datepart.split("-", 2)) + hours, minutes, seconds = map(int, timepart.split(":")) + return datetime.datetime(year, month, day, hours, minutes, seconds) + assert(isinstance(value, datetime.datetime)) + value.replace(microsecond=0) + return value + + +class Timestamp(Field): + + @staticmethod + def sql_format(value): + if not value: + return None + if isinstance(value, basestring): + datepart, timepart = value.split(" ") + year, month, day = map(int, datepart.split("-", 2)) + timepart_full = timepart.split(".", 1) + hours, minutes, seconds = map(int, timepart_full[0].split(":")) + if len(timepart_full) == 2: + microseconds = int(timepart_full[1]) + else: + microseconds = 0 + return datetime.datetime(year, month, day, hours, minutes, seconds, + microseconds) + assert(isinstance(value, datetime.datetime)) + return value class Time(Field): diff --git a/trytond/backend/postgresql/fields.py b/trytond/backend/postgresql/fields.py index 3689de740e..e3feee5407 100644 --- a/trytond/backend/postgresql/fields.py +++ b/trytond/backend/postgresql/fields.py @@ -76,6 +76,13 @@ class DateTime(fields.DateTime): return ('timestamp', 'timestamp(0)') +class Timestamp(fields.Timestamp): + + @staticmethod + def sql_type(field): + return ('timestamp', 'timestamp(6)') + + class Time(fields.Time): @staticmethod @@ -125,6 +132,7 @@ FIELDS = { 'numeric': Numeric, 'date': Date, 'datetime': DateTime, + 'timestamp': Timestamp, 'time': Time, 'binary': Binary, 'selection': Selection, diff --git a/trytond/backend/postgresql/table.py b/trytond/backend/postgresql/table.py index 93b5343978..7fcd4d60bf 100644 --- a/trytond/backend/postgresql/table.py +++ b/trytond/backend/postgresql/table.py @@ -202,6 +202,10 @@ class TableHandler(TableHandlerInterface): def add_raw_column(self, column_name, column_type, column_format, default_fun=None, field_size=None, migrate=True): if self.column_exist(column_name): + if column_name in ('create_date', 'write_date'): + #Migrate dates from timestamp(0) to timestamp + self.cursor.execute('ALTER TABLE "' + self.table_name + '" ' \ + 'ALTER COLUMN "' + column_name + '" TYPE timestamp') if not migrate: return base_type = column_type[0].lower() diff --git a/trytond/backend/sqlite/fields.py b/trytond/backend/sqlite/fields.py index aa39721d48..ca85ba67f3 100644 --- a/trytond/backend/sqlite/fields.py +++ b/trytond/backend/sqlite/fields.py @@ -74,6 +74,13 @@ class DateTime(fields.DateTime): return ('TIMESTAMP', 'TIMESTAMP') +class Timestamp(fields.Timestamp): + + @staticmethod + def sql_type(field): + return ('TIMESTAMP', 'TIMESTAMP') + + class Time(fields.Time): @staticmethod @@ -119,6 +126,7 @@ FIELDS = { 'numeric': Numeric, 'date': Date, 'datetime': DateTime, + 'timestamp': Timestamp, 'time': Time, 'binary': Binary, 'selection': Selection, diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py index a74c028f35..d12ff6c3af 100644 --- a/trytond/model/modelsql.py +++ b/trytond/model/modelsql.py @@ -62,13 +62,13 @@ class ModelSQL(ModelStorage): table = TableHandler(cursor, self, module_name) if self._history: history_table = TableHandler(cursor, self, module_name, history=True) - datetime_field = FIELDS['datetime'] + timestamp_field = FIELDS['timestamp'] integer_field = FIELDS['integer'] logs = ( - ('create_date', datetime_field.sql_type(None), - datetime_field.sql_format, lambda *a: datetime.datetime.now()), - ('write_date', datetime_field.sql_type(None), - datetime_field.sql_format, None), + ('create_date', timestamp_field.sql_type(None), + timestamp_field.sql_format, lambda *a: datetime.datetime.now()), + ('write_date', timestamp_field.sql_type(None), + timestamp_field.sql_format, None), ('create_uid', (integer_field.sql_type(None)[0], 'INTEGER REFERENCES res_user ON DELETE SET NULL',), integer_field.sql_format, lambda *a: 0), @@ -81,10 +81,10 @@ class ModelSQL(ModelStorage): default_fun=log[3], migrate=False) if self._history: history_logs = ( - ('create_date', datetime_field.sql_type(None), - datetime_field.sql_format), - ('write_date', datetime_field.sql_type(None), - datetime_field.sql_format), + ('create_date', timestamp_field.sql_type(None), + timestamp_field.sql_format), + ('write_date', timestamp_field.sql_type(None), + timestamp_field.sql_format), ('create_uid', (integer_field.sql_type(None)[0], 'INTEGER REFERENCES res_user ON DELETE SET NULL',), integer_field.sql_format),