Issue: Cast to db_value for insert queries
Author: alexlatchford
State: closed
Created: 2014-09-16 00:46:27

I was getting problems with foreign key fields not being cast properly, looks like this is the solution. It's not well tested so you might want to have a play yourself before accepting.

``` python
class MyModel(Model):
     uuid = UUIDField(primary_key=True)

class MyRelatedModel(Model):
     name = CharField()
     my_model = ForeignKeyField(MyModel)

my_model = MyModel.get(...)
MyRelatedModel.select(MyRelatedModel.my_model == my_model)
```

Should output something similar to:

```
HTTP Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/cherrypy/_cprequest.py", line 656, in respond
    response.body = self.handler()
  File "/Library/Python/2.7/site-packages/cherrypy/lib/encoding.py", line 188, in __call__
    self.body = self.oldhandler(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/cherrypy/_cpdispatch.py", line 34, in __call__
    return self.callable(*self.args, **self.kwargs)
  File "/Users/alexlatchford/Code/abbreviate/a8-product/a8_product/../a8_product/lib/auth_tools.py", line 11, in __ca
    return f(*args, **kwargs)
  File "/Users/alexlatchford/Code/abbreviate/a8-product/a8_product/../a8_product/routes/auth/signup.py", line 95, in POST
    NewsFilterKeyword.insert_many(news_filter_keywords).execute()
  File "/Users/alexlatchford/Code/peewee/peewee.py", line 2564, in execute
    return self.database.last_insert_id(self._execute(), self.model_class)
  File "/Users/alexlatchford/Code/peewee/peewee.py", line 2126, in _execute
    return self.database.execute_sql(sql, params, self.require_commit)
  File "/Users/alexlatchford/Code/peewee/playhouse/postgres_ext.py", line 289, in execute_sql
    self.commit()
  File "/Users/alexlatchford/Code/peewee/peewee.py", line 2600, in __exit__
    reraise(new_type, new_type(*exc_value.args), traceback)
  File "/Users/alexlatchford/Code/peewee/playhouse/postgres_ext.py", line 282, in execute_sql
    res = cursor.execute(sql, params or ())
ProgrammingError: can't adapt type 'UUID'
```

Thanks,
Alex


I thought I had commented on this, but looks like it did not get saved. At any rate, I believe that peewee should already be converting values using the associated field's `db_value`. If you take a look at `QueryCompiler.generate_insert`, you'll see this code:

``` python
            for row_dict in query._iter_rows():
                if not have_fields:
                    fields = sorted(
                        row_dict.keys(), key=operator.attrgetter('_sort_key'))
                    have_fields = True

                values = []
                for field in fields:
                    value = row_dict[field]
                    if not isinstance(value, (Node, Model)):
                        value = Param(value, conv=field.db_value)
                    values.append(value)

                value_clauses.append(EnclosedClause(*values))
```

Essentially, any values that are not `Node` or `Model` instances, will be parameterized. Additionally, the field's db_value method will be used to convert to the `Param`. In `QueryCompiler._parse_param`:

``` python
    def _parse_param(self, node, alias_map, conv):
        if node.conv:
            params = [node.conv(node.value)]
        else:
            params = [node.value]
        return self.interpolation, params
```

Can you explain a bit more what problem you encountered?


Whoops I think I wrote the example for another bug instead of this one. This was my initial attempt at monkey patching the other issue I reported yesterday (that you fixed properly!).

I'll close this one and open a separate issue, sorry for time wasting, had a lot on my mind yesterday I guess.


Good news is I just updated to the latest copy of master and played around with the example code above and cannot reproduce the bug so either my code is wrong or it's fixed already. Either way thanks a lot for investigating, great to get problems fixed so quickly!!