Merge pull request #46 from 3onyc/issue-34

Implement SQLite datetime fix (Fixes #34)
This commit is contained in:
Friedrich Lindenberg 2014-01-05 09:39:48 -08:00
commit 382703f753
2 changed files with 30 additions and 2 deletions

View File

@ -4,6 +4,7 @@ import warnings
warnings.filterwarnings(
'ignore', 'Unicode type received non-unicode bind param value.')
from dataset.persistence.util import sqlite_datetime_fix
from dataset.persistence.database import Database
from dataset.persistence.table import Table
from dataset.freeze.app import freeze
@ -27,4 +28,8 @@ def connect(url=None, schema=None, reflectMetadata=True):
"""
if url is None:
url = os.environ.get('DATABASE_URL', url)
if url.startswith("sqlite://"):
sqlite_datetime_fix()
return Database(url, schema=schema, reflectMetadata=reflectMetadata)

View File

@ -1,11 +1,11 @@
from datetime import datetime
from datetime import datetime, timedelta
from inspect import isgenerator
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict # Python < 2.7 drop-in
from sqlalchemy import Integer, UnicodeText, Float, DateTime, Boolean
from sqlalchemy import Integer, UnicodeText, Float, DateTime, Boolean, types, Table, event
def guess_type(sample):
@ -56,3 +56,26 @@ class ResultIter(object):
def __iter__(self):
return self
def sqlite_datetime_fix():
class SQLiteDateTimeType(types.TypeDecorator):
impl = types.Integer
epoch = datetime(1970, 1, 1, 0, 0, 0)
def process_bind_param(self, value, dialect):
return (value / 1000 - self.epoch).total_seconds()
def process_result_value(self, value, dialect):
return self.epoch + timedelta(seconds=value / 1000)
def is_sqlite(inspector):
return inspector.engine.dialect.name == "sqlite"
def is_datetime(column_info):
return isinstance(column_info['type'], types.DateTime)
@event.listens_for(Table, "column_reflect")
def setup_epoch(inspector, table, column_info):
if is_sqlite(inspector) and is_datetime(column_info):
column_info['type'] = SQLiteDateTimeType()