Skip to content
This repository was archived by the owner on Mar 20, 2026. It is now read-only.
This repository was archived by the owner on Mar 20, 2026. It is now read-only.

Fix missing inferred types in insert statements #566

@c24t

Description

@c24t

If we call transaction.execute_sql with missing parameters in param_types, we may not get an error until iterating over the over the ResultSet (even if it's empty). This errors is: InvalidArgument('Unable to infer type for parameter ....').

spanner_dbapi.parse_utils.get_param_types
infers spanner data types from the python types. This is called downstream of django's CursorWrapper.execute. Among other problems, this means that we can't infer the spanner type for None-valued fields, and so they aren't included in param_types.

This problem shows up following the django tutorial at manage.py createsuperuser, which results in these arguments to transaction.execute_sql:

sql="INSERT INTO auth_user (id, password, last_login, is_superuser, username, first_name, last_name, email, is_staff, is_active, date_joined) VALUES (@a0, @a1, @a2, @a3, @a4, @a5, @a6, @a7, @a8, @a9, @a10)"

params={'a0': 1451803748860449997,
 'a1': (hashed pwd),
 'a2': None,
 'a3': True,
 'a4': (username),
 'a5': '',
 'a6': '',
 'a7': '',
 'a8': True,
 'a9': True,
 'a10': '2020-12-14T23:57:50.577202Z'}

param_types={'a0': code: INT64,
 'a1': code: STRING,
 'a3': code: BOOL,
 'a4': code: STRING,
 'a5': code: STRING,
 'a6': code: STRING,
 'a7': code: STRING,
 'a8': code: BOOL,
 'a9': code: BOOL,
 'a10': code: TIMESTAMP}

Note that a2 is missing from param_types. The field last_login should be a google.cloud.spanner_v1.param_types.TIMESTAMP, but we can't infer it before the call.

Interestingly we only see the InvalidArgument error when using the emulator. The real non-emulated spanner service handles this insert without error.

This problem is at least as old as 47154d1, and existed in the spanner_dbapi package in this repo before it was moved into python-spanner.

It's not clear whether the right fix for this problem is here, in python-spanner, or in the emulator. But it does prevent us from using the emulator with apps that have models with nullable fields, including the django tutorial app.

Metadata

Metadata

Assignees

No one assigned

    Labels

    🚨This issue needs some love.api: spannerIssues related to the googleapis/python-spanner-django API.priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions