Issue: entering datetime with timezone results in illegal SQL INSERT
Author: shikasta-net
State: closed
Created: 2014-03-13 11:51:59

When attempting to INSERT key values pairs, where the value is an instance datetime.datetime(2014, 1, 12, 14, 0, tzinfo=<UTC>), peewee converts these (via datetime's default to string encoding) to 2014-01-12 15:00:00+00:00 which is not a valid format for MySQL. The timezone information should be ignored as MySQL only accepts 0000-00-00 00:00:00, or variants, without +00:00 at the end. Oddly, this problem only occurs when the script is run on a Windows Server 2012. The problem does not exist for Linux despite both using the same datetime to string conversion.

I think this can be fixed by giving all TimeField classes a `db_value` function which does the inverse of the existing `format_date_time` function, overriding the default datetime to string conversion.
The following monkey patch works in my case, but I think this would be worth implementing properly. 

```
def format_date_time(value, formats, post_process=None):
    post_process = post_process or (lambda x: x)
    for fmt in formats:
        try:
            if isinstance(value, datetime):
                return value.strftime(fmt)
            else :
                return post_process(datetime.datetime.strptime(value, fmt))

        except ValueError:
            pass
    return value


class DateTimeField(peewee._BaseFormattedField):
    db_field = 'datetime'
    formats = [
        '%Y-%m-%d %H:%M:%S.%f',
        '%Y-%m-%d %H:%M:%S',
        '%Y-%m-%d',
    ]

    def python_value(self, value):
        if value and isinstance(value, basestring):
            return format_date_time(value, self.formats)
        return value

    def db_value(self, value):
        if value and isinstance(value, datetime):
            return format_date_time(value, self.formats)
        return value

    year = property(peewee._date_part('year'))
    month = property(peewee._date_part('month'))
    day = property(peewee._date_part('day'))
    hour = property(peewee._date_part('hour'))
    minute = property(peewee._date_part('minute'))
    second = property(peewee._date_part('second'))


peewee.format_date_time = format_date_time
peewee.DateTimeField = DateTimeField
```


Peewee is not converting the date to a string when it sends it to MySQL. Instead, the MySQL adapter is probably doing the conversion for you. Are you using different versions of MySQLdb or pymysql between your two machines?

If you'd like to implement this more cleanly, you can subclass `DateTimeField` and implement one that removes the timezone before sending it to the database:

``` python
class NoTZDateTimeField(DateTimeField):
    def db_value(self, value):
        return value.replace(tzinfo=None)  # I think this should do it
```

Then you'd replace your fields with the NoTZDateTimeField.

Please give that a shot and let me know!


My apology for not having dug far enough through the dependencies, I assumed the datetime conversion was done when it was cast to string. Seems you were right, version 1.2.3 MySQLdb works but 1.2.5 does not (it seems the repository version for linux is behind that of PyPI). I can't find another work around, but your suggested fix is better than mine.