Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions google/cloud/bigquery/dbapi/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ def bigquery_scalar_type(value):
elif isinstance(value, numbers.Real):
return "FLOAT64"
elif isinstance(value, decimal.Decimal):
if pyarrow is None:
# We don't try to manually guess if it's maybe a BIGNUMERIC.
return "NUMERIC"

# We check for NUMERIC before BIGNUMERIC in order to support pyarrow < 3.0.
scalar_object = pyarrow.scalar(value)
if isinstance(scalar_object, pyarrow.Decimal128Scalar):
Expand Down
37 changes: 30 additions & 7 deletions tests/unit/test_dbapi__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import math
import operator as op
import unittest
from unittest import mock

try:
import pyarrow
Expand All @@ -41,7 +42,7 @@ def test_scalar_to_query_parameter(self):
(1.25, "FLOAT64"),
(decimal.Decimal("1.25"), "NUMERIC"),
(b"I am some bytes", "BYTES"),
(u"I am a string", "STRING"),
("I am a string", "STRING"),
(datetime.date(2017, 4, 1), "DATE"),
(datetime.time(12, 34, 56), "TIME"),
(datetime.datetime(2012, 3, 4, 5, 6, 7), "DATETIME"),
Expand Down Expand Up @@ -71,6 +72,28 @@ def test_scalar_to_query_parameter(self):
self.assertEqual(named_parameter.type_, expected_type, msg=msg)
self.assertEqual(named_parameter.value, value, msg=msg)

def test_decimal_to_query_parameter_no_pyarrow(self):
# The value should have a high-enough scale to be recognized as BIGNUMERIC
# if pyarrow was available.
value = decimal.Decimal("1.1234567890123456789012345678901234567890")
msg = f"value: {value} expected_type: NUMERIC"

patcher = mock.patch("google.cloud.bigquery.dbapi._helpers.pyarrow", new=None)

with patcher:
parameter = _helpers.scalar_to_query_parameter(value)

self.assertIsNone(parameter.name, msg=msg)
self.assertEqual(parameter.type_, "NUMERIC", msg=msg)
self.assertEqual(parameter.value, value, msg=msg)

with patcher:
named_parameter = _helpers.scalar_to_query_parameter(value, name="myvar")

self.assertEqual(named_parameter.name, "myvar", msg=msg)
self.assertEqual(named_parameter.type_, "NUMERIC", msg=msg)
self.assertEqual(named_parameter.value, value, msg=msg)

def test_scalar_to_query_parameter_w_unexpected_type(self):
with self.assertRaises(exceptions.ProgrammingError):
_helpers.scalar_to_query_parameter(value={"a": "dictionary"})
Expand All @@ -90,7 +113,7 @@ def test_array_to_query_parameter_valid_argument(self):
([1.25, 2.50], "FLOAT64"),
([decimal.Decimal("1.25")], "NUMERIC"),
([b"foo", b"bar"], "BYTES"),
([u"foo", u"bar"], "STRING"),
(["foo", "bar"], "STRING"),
([datetime.date(2017, 4, 1), datetime.date(2018, 4, 1)], "DATE"),
([datetime.time(12, 34, 56), datetime.time(10, 20, 30)], "TIME"),
(
Expand Down Expand Up @@ -134,7 +157,7 @@ def test_array_to_query_parameter_empty_argument(self):
_helpers.array_to_query_parameter([])

def test_array_to_query_parameter_unsupported_sequence(self):
unsupported_iterables = [{10, 20, 30}, u"foo", b"bar", bytearray([65, 75, 85])]
unsupported_iterables = [{10, 20, 30}, "foo", b"bar", bytearray([65, 75, 85])]
for iterable in unsupported_iterables:
with self.assertRaises(exceptions.ProgrammingError):
_helpers.array_to_query_parameter(iterable)
Expand All @@ -144,7 +167,7 @@ def test_array_to_query_parameter_sequence_w_invalid_elements(self):
_helpers.array_to_query_parameter([object(), 2, 7])

def test_to_query_parameters_w_dict(self):
parameters = {"somebool": True, "somestring": u"a-string-value"}
parameters = {"somebool": True, "somestring": "a-string-value"}
query_parameters = _helpers.to_query_parameters(parameters)
query_parameter_tuples = []
for param in query_parameters:
Expand All @@ -154,7 +177,7 @@ def test_to_query_parameters_w_dict(self):
sorted(
[
("somebool", "BOOL", True),
("somestring", "STRING", u"a-string-value"),
("somestring", "STRING", "a-string-value"),
]
),
)
Expand All @@ -177,14 +200,14 @@ def test_to_query_parameters_w_dict_dict_param(self):
_helpers.to_query_parameters(parameters)

def test_to_query_parameters_w_list(self):
parameters = [True, u"a-string-value"]
parameters = [True, "a-string-value"]
query_parameters = _helpers.to_query_parameters(parameters)
query_parameter_tuples = []
for param in query_parameters:
query_parameter_tuples.append((param.name, param.type_, param.value))
self.assertSequenceEqual(
sorted(query_parameter_tuples),
sorted([(None, "BOOL", True), (None, "STRING", u"a-string-value")]),
sorted([(None, "BOOL", True), (None, "STRING", "a-string-value")]),
)

def test_to_query_parameters_w_list_array_param(self):
Expand Down