Skip to content

Commit

Permalink
feat: support float32 parameters in dbapi
Browse files Browse the repository at this point in the history
dbapi should not add an explicit type code when a parameter of type
float is encountered. Instead, it should rely on Spanner to infer
the correct type. This way, both FLOAT32 and FLOAT64 can be used with
the Python float type.

Updates googleapis/python-spanner-sqlalchemy#409
  • Loading branch information
olavloite committed Dec 2, 2024
1 parent ccae6e0 commit 15ead74
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
9 changes: 8 additions & 1 deletion google/cloud/spanner_dbapi/parse_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@
from .types import DateStr, TimestampStr
from .utils import sanitize_literals_for_upload

# Note: This mapping deliberately does not contain a value for float.
# The reason for that is that it is better to just let Spanner determine
# the parameter type instead of specifying one explicitly. The reason for
# this is that if the client specifies FLOAT64, and the actual column that
# the parameter is used for is of type FLOAT32, then Spanner will return an
# error. If however the client does not specify a type, then Spanner will
# automatically choose the appropriate type based on the column where the
# value will be inserted/updated or that it will be compared with.
TYPES_MAP = {
bool: spanner.param_types.BOOL,
bytes: spanner.param_types.BYTES,
str: spanner.param_types.STRING,
int: spanner.param_types.INT64,
float: spanner.param_types.FLOAT64,
datetime.datetime: spanner.param_types.TIMESTAMP,
datetime.date: spanner.param_types.DATE,
DateStr: spanner.param_types.DATE,
Expand Down
47 changes: 45 additions & 2 deletions tests/system/test_dbapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import base64
import datetime
from collections import defaultdict

import pytest
import time
import decimal

from google.cloud import spanner_v1
from google.cloud._helpers import UTC
Expand Down Expand Up @@ -50,7 +52,22 @@
SQL SECURITY INVOKER
AS
SELECT c.email
FROM contacts AS c;"""
FROM contacts AS c;
CREATE TABLE all_types (
id int64,
col_bool bool,
col_bytes bytes(max),
col_date date,
col_float32 float32,
col_float64 float64,
col_int64 int64,
col_json json,
col_numeric numeric,
col_string string(max),
coL_timestamp timestamp,
) primary key (col_int64);
"""

DDL_STATEMENTS = [stmt.strip() for stmt in DDL.split(";") if stmt.strip()]

Expand Down Expand Up @@ -1602,3 +1619,29 @@ def test_list_tables(self, include_views):
def test_invalid_statement_error(self):
with pytest.raises(ProgrammingError):
self._cursor.execute("-- comment only")

def test_insert_all_types(self):
"""Test inserting all supported data types"""

self._conn.autocommit = True
self._cursor.execute(
"""
INSERT INTO all_types (id, col_bool, col_bytes, col_date, col_float32, col_float64,
col_int64, col_json, col_numeric, col_string, col_timestamp)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
""",
(
1,
True,
base64.b64encode(b"test-bytes"),
datetime.date(2024, 12, 3),
3.14,
3.14,
123,
JsonObject({"key": "value"}),
decimal.Decimal("3.14"),
"test-string",
datetime.datetime(2024, 12, 3, 17, 30, 14),
),
)
assert self._cursor.rowcount == 1
3 changes: 2 additions & 1 deletion tests/unit/spanner_dbapi/test_parse_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ def test_get_param_types(self):
params = {
"a1": 10,
"b1": "string",
# Note: We only want a value and not a type for this.
# Instead, we let Spanner infer the correct type (FLOAT64 or FLOAT32)
"c1": 10.39,
"d1": TimestampStr("2005-08-30T01:01:01.000001Z"),
"e1": DateStr("2019-12-05"),
Expand All @@ -232,7 +234,6 @@ def test_get_param_types(self):
want_types = {
"a1": param_types.INT64,
"b1": param_types.STRING,
"c1": param_types.FLOAT64,
"d1": param_types.TIMESTAMP,
"e1": param_types.DATE,
"f1": param_types.BOOL,
Expand Down

0 comments on commit 15ead74

Please sign in to comment.