Issue: Problem with pymysql + python 2.7
Author: foxx
State: closed
Created: 2016-02-26 16:07:54

Came across this problem when running a full test suite using `pymysql` with `Python 2.7`.

If you attempt to pass in a binary to `BlobField`, it results in the following error upon execution.

```
build/bdist.linux-x86_64/egg/peewee.py:4494: in create
    ???
build/bdist.linux-x86_64/egg/peewee.py:4680: in save
    ???
build/bdist.linux-x86_64/egg/peewee.py:3213: in execute
    ???
build/bdist.linux-x86_64/egg/peewee.py:2628: in _execute
    ???
build/bdist.linux-x86_64/egg/peewee.py:3454: in execute_sql
    ???
.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/cursors.py:156: in execute
    query = self.mogrify(query, args)
.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/cursors.py:135: in mogrify
    query = query % self._escape_args(args, conn)
.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/cursors.py:110: in _escape_args
    return tuple(conn.escape(arg) for arg in args)
.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/cursors.py:110: in <genexpr>
    return tuple(conn.escape(arg) for arg in args)
.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/connections.py:781: in escape
    return escape_item(obj, self.charset, mapping=mapping)
.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/converters.py:26: in escape_item
    val = encoder(val, mapping)
.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/converters.py:109: in escape_unicode
    return u"'%s'" % _escape_unicode(value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

value = <read-only buffer for 0x7f4027d59880, size -1, offset 0 at 0x7f4027d653f0>, mapping = None

    def _escape_unicode(value, mapping=None):
        """escapes *value* without adding quote.

        Value should be unicode
        """
>       return value.translate(_escape_table)
E       AttributeError: 'buffer' object has no attribute 'translate'

mapping    = None
value      = <read-only buffer for 0x7f4027d59880, size -1, offset 0 at 0x7f4027d653f0>

.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/converters.py:72: AttributeError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> /vagrant/peewee-extras/.eggs/PyMySQL-0.7.2-py2.7.egg/pymysql/converters.py(72)_escape_unicode()
-> return value.translate(_escape_table)
```

Code to reproduce the problem;

```
class TestModel(Model):
    value = BlobField()

v = binascii.unhexlify('0a0a0a')
OrderedUUIDModel.create(value=str(v))
```


I'm not quite sure I understand... what's going on here?


Sorry here's an exact code snippet to reproduce the problem with `pymysql` and `python 2.7.11`.

The same code works as expected with `sqlite` and `postgres`.

``` python
from peewee import BlobField, Model
from playhouse.db_url import connect

db = connect('mysql://root@127.0.0.1/peewee_test')

class ExampleModel(Model):
    class Meta:
        database = db
    value = BlobField()

ExampleModel.drop_table()
ExampleModel.create_table()
ExampleModel.create(value='1234')
```

Result;

```
$ python hello.py
Traceback (most recent call last):
  File "hello.py", line 13, in <module>
    ExampleModel.create(value='1234')
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/peewee.py", line 4494, in create
    inst.save(force_insert=True)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/peewee.py", line 4680, in save
    pk_from_cursor = self.insert(**field_dict).execute()
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/peewee.py", line 3213, in execute
    cursor = self._execute()
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/peewee.py", line 2628, in _execute
    return self.database.execute_sql(sql, params, self.require_commit)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/peewee.py", line 3454, in execute_sql
    cursor.execute(sql, params or ())
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/pymysql/cursors.py", line 156, in execute
    query = self.mogrify(query, args)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/pymysql/cursors.py", line 135, in mogrify
    query = query % self._escape_args(args, conn)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/pymysql/cursors.py", line 110, in _escape_args
    return tuple(conn.escape(arg) for arg in args)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/pymysql/cursors.py", line 110, in <genexpr>
    return tuple(conn.escape(arg) for arg in args)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/pymysql/connections.py", line 781, in escape
    return escape_item(obj, self.charset, mapping=mapping)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/pymysql/converters.py", line 26, in escape_item
    val = encoder(val, mapping)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/pymysql/converters.py", line 109, in escape_unicode
    return u"'%s'" % _escape_unicode(value)
  File "/home/vagrant/.pyenv/versions/2.7.11/lib/python2.7/site-packages/pymysql/converters.py", line 72, in _escape_unicode
    return value.translate(_escape_table)
AttributeError: 'buffer' object has no attribute 'translate'
```


This should be fixed. The `BlobField` will now use the database-drivers `Binary` column type.

b32e967e933c0d9d029f3385a5a115c46beacd03


Awesome, I'll let you know if I run into any problems, thanks for the quick response!


I am getting a similar error:

```
/vagrant/data/ida_generate_trace.py: 'buffer' object has no attribute 'translate'

File "/vagrant/data/trace_to_db.py", line 59, in add_initial_memory_areas_to_trace
    peewee_memory_area.save()
  File "/opt/Python2.7-32bit/lib/python2.7/site-packages/peewee.py", line 4680, in save
    pk_from_cursor = self.insert(**field_dict).execute()
  File "/opt/Python2.7-32bit/lib/python2.7/site-packages/peewee.py", line 3213, in execute
    cursor = self._execute()
  File "/opt/Python2.7-32bit/lib/python2.7/site-packages/peewee.py", line 2628, in _execute
    return self.database.execute_sql(sql, params, self.require_commit)
```

The memory area looks like this:

```
class MemoryArea(Model):
    trace = ForeignKeyField(Trace, related_name='initial_memory_areas')
    start_addr = BigIntegerField()
    size = BigIntegerField()
    memory_content = BlobField(null=True)

    class Meta:
        database = db
```

I am using `MySQLDatabase`.

Is this the same issue? I installed peewee via pip. It says version 

> 2.8.0


BTW: If I change the db to `SqliteDatabase`, I am getting a different error

```
/vagrant/data/ida_generate_trace.py: Python int too large to convert to SQLite INTEGER
Traceback (most recent call last):
  [...]
    peewee_memory_area.save()
  File "/opt/Python2.7-32bit/lib/python2.7/site-packages/peewee.py", line 4680, in save
    pk_from_cursor = self.insert(**field_dict).execute()
  File "/opt/Python2.7-32bit/lib/python2.7/site-packages/peewee.py", line 3213, in execute
    cursor = self._execute()
  File "/opt/Python2.7-32bit/lib/python2.7/site-packages/peewee.py", line 2628, in _execute
    return self.database.execute_sql(sql, params, self.require_commit)
```


Looks like the same problem, although you're getting a different error with Sqlite because it's passing the driver layer and actually executing the SQ (afaik), and I think the most recent patch in master might not resolve this issue (as that relates to blob fields only from what I can tell)

/cc @coleifer Any update on that new release? :P


The SQLite one may be related to the integer fields as far as I can tell from the traceback. SQLite doesn't have a big integer field, so you may need to store those as text.


Prob need a new release to fix the blob thing, though, as @foxx said. I'll try and get one together soon


Thank you. I would really appreciate it. I like peewee and would like to use it for my current project, and future ones.  For the moment, I am kind of stuck with this bug. 

Sent from Outlook Mobile


You can always point at master, but I understand what you're saying and will try and get this done tonight.


@coleifer Happy to throw a pair of hands on this, if there's anything I can do to help (testing, docs or w/e)


@gitttt If you're really stuck and not sure how to install from master, let me know and I'll post some instructions up for you.


Oh, I did not understand you correctly. So you have fixed this problem already? I will try to point at master and check if it works.


I re-installed peewee. This time from the github repo. The error is gone.


I got the same error.
I degraded PyMySQL from (0.7.2) to (0.6.6). It works for me.
My peewee version is 2.8.0


I was having all sorts of problems like this with PyMySQL (0.7.2 and 0.6.6). I switched to MySQLdb and everything is good.