Search code examples
pythondjangogoogle-app-enginegoogle-cloud-sql

InterfaceError unknown type <class 'decimal.Decimal'> for arg 10


I'm trying to fetch some data from my database., this works perfect on my local machine. But when deployed on Google App Engine it gives me an error

InterfaceError at /report/unit/D8500/WV_herverkoop/2013/0/10/ unknown type <class 'decimal.Decimal'> for arg 10

full traceback

    InterfaceError at /report/unit/D8500/WV_herverkoop/2013/0/10/
unknown type <class 'decimal.Decimal'> for arg 10
Request Method: GET
Request URL:    http://dw-services.appspot.com/report/unit/D8500/WV_herverkoop/2013/0/10/
Django Version: 1.4.3
Exception Type: InterfaceError
Exception Value:    
unknown type <class 'decimal.Decimal'> for arg 10
Exception Location: /python27_runtime/python27_lib/versions/1/google/storage/speckle/python/api/rdbms.py in _AddBindVariablesToRequest, line 427
Python Executable:  /python27_runtime/python27_dist/python
Python Version: 2.7.3
Python Path:    
['/base/data/home/apps/s~dw-services/2.365787501016750085',
 '/python27_runtime/python27_dist/lib/python27.zip',
 '/python27_runtime/python27_dist/lib/python2.7',
 '/python27_runtime/python27_dist/lib/python2.7/plat-linux2',
 '/python27_runtime/python27_dist/lib/python2.7/lib-tk',
 '/python27_runtime/python27_dist/lib/python2.7/lib-old',
 '/python27_runtime/python27_dist/lib/python2.7/lib-dynload',
 '/python27_runtime/python27_dist/lib/python2.7/site-packages',
 '/python27_runtime/python27_lib/versions/1',
 '/python27_runtime/python27_lib/versions/third_party/django-1.4',
 '/python27_runtime/python27_lib/versions/third_party/webapp2-2.3',
 '/python27_runtime/python27_lib/versions/third_party/webob-1.1.1',
 '/python27_runtime/python27_lib/versions/third_party/yaml-3.10',
 '/base/data/home/apps/s~dw-services/2.365787501016750085/..']
Server time:    don, 7 Mrt 2013 13:58:28 +0000
Traceback Switch to copy-and-paste view

/python27_runtime/python27_lib/versions/third_party/django-1.4/django/core/handlers/base.py in get_response
                        response = callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
/python27_runtime/python27_lib/versions/third_party/django-1.4/django/contrib/auth/decorators.py in _wrapped_view
                return view_func(request, *args, **kwargs) ...
▶ Local vars
/base/data/home/apps/s~dw-services/2.365787501016750085/dewaelereports/views/reportView.py in showReportPerOffice
        position = 0           # position in which we'll insert the region
        region_commission = 0  # commission earned in a region
        region_count = 0       # transactions in a region
        region_avg = 0         # average in a region
        counter = 0            # detect when it's the first zip in the region
        for zip in region.zips.all():
            results = zip.get_total_sales(office, start_week, end_week, year, unit_type) ...
            total_count += results[0][0]
            total_commission += results[0][1]
            region_count += results[0][0]
            region_commission += results[0][1]
            zipList.append((zip.zip_name, results[0], results[1]))
            if counter == 0:
▶ Local vars
/base/data/home/apps/s~dw-services/2.365787501016750085/dewaelereports/models.py in get_total_sales
        return [calculate_results(zip_transactions, unit), zip_transactions] ...
▼ Local vars
Variable    Value
office  
<Office: D8500>
transactions    
[<Transaction: k08071>, <Transaction: T8500-08157C>, <Transaction: D8500-11451>, <Transaction: D8500-12042H>, <Transaction: D8500-12143B>, <Transaction: T8500-09259>, <Transaction: T8500-10244a>, <Transaction: T8500-10277>, <Transaction: T8500-10277>, <Transaction: D8500-10345-A12>, <Transaction: T8500-10420>, <Transaction: T8500-10496>, <Transaction: T8500-11040H>, <Transaction: D8500-11048>, <Transaction: D8500-11650H>, <Transaction: D8500-11255B>, <Transaction: T8500-11325>, <Transaction: D8500-11343H>, <Transaction: T8500-11497>, <Transaction: D8500-11508B>, '...(remaining elements truncated)...']
start_week  
u'0'
self    
<Zip: 8500 - Kortrijk>
zip_transactions    
[<Office_per_transaction: 2460>, <Office_per_transaction: 2413>, <Office_per_transaction: 775>, <Office_per_transaction: 2477>, <Office_per_transaction: 2414>, <Office_per_transaction: 2485>]
unit    
<Unit_type: WV herverkoop>
year    
u'2013'
office_transactions 
[<Office_per_transaction: 196>, <Office_per_transaction: 1111>, <Office_per_transaction: 2460>, <Office_per_transaction: 2433>, <Office_per_transaction: 1105>, <Office_per_transaction: 1135>, <Office_per_transaction: 2413>, <Office_per_transaction: 775>, <Office_per_transaction: 3176>, <Office_per_transaction: 3444>, <Office_per_transaction: 2477>, <Office_per_transaction: 2414>, <Office_per_transaction: 1094>, <Office_per_transaction: 2485>]
end_week    
u'10'
/base/data/home/apps/s~dw-services/2.365787501016750085/dewaelereports/models.py in calculate_results
    if len(transaction_query) >= 1:
        sum = 0
        for tr in transaction_query:
            sum += tr.transaction.commission_fix_out * (tr.office_percentage / 100)
        if unit:
            if unit.min_quantity:
                count_transactions = len(transaction_query.filter(transaction__transaction_price_out__gt=str(unit.min_quantity))) ...
        if not unit or not unit.min_quantity:
            count_transactions = len(transaction_query)
        avg = sum / len(transaction_query)
▼ Local vars
Variable    Value
transaction_query   
[<Office_per_transaction: 2460>, <Office_per_transaction: 2413>, <Office_per_transaction: 775>, <Office_per_transaction: 2477>, <Office_per_transaction: 2414>, <Office_per_transaction: 2485>]
count_transactions  
0
sum 
Decimal('61313.0300')
tr  
<Office_per_transaction: 2485>
avg 
0
unit    
<Unit_type: WV herverkoop>
/python27_runtime/python27_lib/versions/third_party/django-1.4/django/db/models/query.py in __len__
                self._result_cache = list(self.iterator()) ...
▶ Local vars
/python27_runtime/python27_lib/versions/third_party/django-1.4/django/db/models/query.py in iterator
        for row in compiler.results_iter(): ...
▶ Local vars
/python27_runtime/python27_lib/versions/third_party/django-1.4/django/db/models/sql/compiler.py in results_iter
        for rows in self.execute_sql(MULTI): ...
▶ Local vars
/python27_runtime/python27_lib/versions/third_party/django-1.4/django/db/models/sql/compiler.py in execute_sql
        cursor.execute(sql, params) ...
▶ Local vars
/python27_runtime/python27_lib/versions/third_party/django-1.4/django/db/backends/util.py in execute
            return self.cursor.execute(sql, params) ...
▶ Local vars
/python27_runtime/python27_lib/versions/third_party/django-1.4/django/db/backends/mysql/base.py in execute
            return self.cursor.execute(query, args) ...
▶ Local vars
/python27_runtime/python27_lib/versions/1/google/storage/speckle/python/api/rdbms.py in execute
    request = sql_pb2.ExecRequest()
    request.options.include_generated_keys = True
    if args is not None:
      if not hasattr(args, '__iter__'):
        args = [args]
      self._AddBindVariablesToRequest(
          statement, args, request.bind_variable.add) ...
    request.statement = _ConvertFormatToQmark(statement, args)
    self._DoExec(request)
    self._executed = request.statement
  def executemany(self, statement, seq_of_args):
    """Prepares and executes a database operation for given parameter sequences.
▼ Local vars
Variable    Value
self    
<google.storage.speckle.python.api.rdbms.Cursor object at 0xfc8c0b10>
args    
(1,
 0,
 10,
 '2013-01-01 00:00:00',
 '2013-12-31 23:59:59.99',
 'R',
 'S',
 13,
 2,
 1459,
 Decimal('75000'))
request 
<google.storage.speckle.proto.sql_pb2.ExecRequest object at 0xfc8a6458>
statement   
'SELECT `dewaelereports_office_per_transaction`.`id`, `dewaelereports_office_per_transaction`.`office_id`, `dewaelereports_office_per_transaction`.`transaction_id`, `dewaelereports_office_per_transaction`.`office_percentage` FROM `dewaelereports_office_per_transaction` INNER JOIN `dewaelereports_transaction` ON (`dewaelereports_office_per_transaction`.`transaction_id` = `dewaelereports_transaction`.`id`) WHERE (`dewaelereports_office_per_transaction`.`office_id` = %s  AND `dewaelereports_transaction`.`transaction_end_week` BETWEEN %s and %s AND `dewaelereports_transaction`.`transaction_end_date` BETWEEN %s and %s AND `dewaelereports_transaction`.`transaction_end_status` IN (%s, %s) AND `dewaelereports_office_per_transaction`.`transaction_id` IN (SELECT U0.`transaction_id` FROM `dewaelereports_transaction_status` U0 WHERE U0.`status` = %s ) AND `dewaelereports_transaction`.`unit_type_id` = %s  AND `dewaelereports_office_per_transaction`.`transaction_id` IN (SELECT U0.`id` FROM `dewaelereports_transaction` U0 INNER JOIN `dewaelereports_property` U1 ON (U0.`premises_id` = U1.`id`) WHERE U1.`property_zip_id` = %s ) AND `dewaelereports_transaction`.`transaction_price_out` > %s )'
/python27_runtime/python27_lib/versions/1/google/storage/speckle/python/api/rdbms.py in _AddBindVariablesToRequest
          raise InterfaceError('unknown type %s for arg %d' % (type(arg), i)) ...
▼ Local vars
Variable    Value
direction   
1
i   
10
bind_variable_factory   
<bound method RepeatedCompositeFieldContainer.add of [<google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c14c8>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c17a0>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c1960>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c1998>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c1f10>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c1dc0>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c17d8>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c1c70>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c15a8>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c1d50>, <google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c1ed8>]>
args    
(1,
 0,
 10,
 '2013-01-01 00:00:00',
 '2013-12-31 23:59:59.99',
 'R',
 'S',
 13,
 2,
 1459,
 Decimal('75000'))
bv  
<google.storage.speckle.proto.client_pb2.BindVariableProto object at 0xfc8c1ed8>
statement   
'SELECT `dewaelereports_office_per_transaction`.`id`, `dewaelereports_office_per_transaction`.`office_id`, `dewaelereports_office_per_transaction`.`transaction_id`, `dewaelereports_office_per_transaction`.`office_percentage` FROM `dewaelereports_office_per_transaction` INNER JOIN `dewaelereports_transaction` ON (`dewaelereports_office_per_transaction`.`transaction_id` = `dewaelereports_transaction`.`id`) WHERE (`dewaelereports_office_per_transaction`.`office_id` = %s  AND `dewaelereports_transaction`.`transaction_end_week` BETWEEN %s and %s AND `dewaelereports_transaction`.`transaction_end_date` BETWEEN %s and %s AND `dewaelereports_transaction`.`transaction_end_status` IN (%s, %s) AND `dewaelereports_office_per_transaction`.`transaction_id` IN (SELECT U0.`transaction_id` FROM `dewaelereports_transaction_status` U0 WHERE U0.`status` = %s ) AND `dewaelereports_transaction`.`unit_type_id` = %s  AND `dewaelereports_office_per_transaction`.`transaction_id` IN (SELECT U0.`id` FROM `dewaelereports_transaction` U0 INNER JOIN `dewaelereports_property` U1 ON (U0.`premises_id` = U1.`id`) WHERE U1.`property_zip_id` = %s ) AND `dewaelereports_transaction`.`transaction_price_out` > %s )'
arg 
Decimal('75000')
self    
<google.storage.speckle.python.api.rdbms.Cursor object at 0xfc8c0b10>

Obviously it fails because it says that unit.min_quantity is a decimal. But i didn't declare it as a Decimal in my models:

class Unit_type(models.Model):
    unit_name = models.CharField(max_length=145)
    department = models.ForeignKey(Department)
    min_quantity = models.IntegerField(blank=True, null=True)

    class Meta:
        verbose_name = 'unit type'

    def __unicode__(self):
        return self.unit_name

When I fill out the statement and execute it manually in Google Cloud Sql, it does work. Can someone help me with this nasty issue?

Thanks


Solution

  • The Google Cloud SQL DBAPI currently does not support the decimal.Decimal type, although you can monkey patch it to:

    import decimal  
    from google.storage.speckle.proto import jdbc_type
    
    from google.storage.speckle.python.api import converters  
    from google.storage.speckle.python.api import rdbms  
    from google.storage.speckle.python.api import rdbms_googleapi
    
    rdbms._PYTHON_TYPE_TO_JDBC_TYPE[decimal.Decimal] = jdbc_type.DECIMAL  
    converters.conversions[decimal.Decimal] = converters.Any2Str  
    converters.conversions[jdbc_type.DECIMAL] = decimal.Decimal  
    

    There is an issue logged here where a Google representative provided the patch above and indicated they are working on a fix for this.