Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bigquery): check rows arg type in insert_rows() #10174

Merged
merged 5 commits into from
Jan 23, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 12 additions & 4 deletions bigquery/google/cloud/bigquery/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ def delete_table(
raise

def _get_query_results(
self, job_id, retry, project=None, timeout_ms=None, location=None, timeout=None,
self, job_id, retry, project=None, timeout_ms=None, location=None, timeout=None
):
"""Get the query results object for a query job.

Expand Down Expand Up @@ -2355,7 +2355,7 @@ def insert_rows(self, table, rows, selected_fields=None, **kwargs):
str, \
]):
The destination table for the row data, or a reference to it.
rows (Union[Sequence[Tuple], Sequence[dict]]):
rows (Union[Sequence[Tuple], Sequence[Dict]]):
Row data to be inserted. If a list of tuples is given, each
tuple should contain data for each schema field on the
current table and in the same order as the schema fields. If
Expand All @@ -2376,8 +2376,11 @@ def insert_rows(self, table, rows, selected_fields=None, **kwargs):
the mappings describing one or more problems with the row.

Raises:
ValueError: if table's schema is not set
ValueError: if table's schema is not set or `rows` is not a `Sequence`.
"""
if not isinstance(rows, (collections_abc.Sequence, collections_abc.Iterator)):
raise TypeError("rows argument should be a sequence of dicts or tuples")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding Iterator too as insert_rows_from_dataframe() calls insert_rows() with iterator returned by itertools.islice. dict still will give a False at this statement


table = _table_arg_to_table(table, default_project=self.project)

if not isinstance(table, Table):
Expand Down Expand Up @@ -2505,8 +2508,13 @@ def insert_rows_json(
One mapping per row with insert errors: the "index" key
identifies the row, and the "errors" key contains a list of
the mappings describing one or more problems with the row.

Raises:
TypeError: if `json_rows` is not a `Sequence`.
"""
if not isinstance(json_rows, collections_abc.Sequence):
if not isinstance(
json_rows, (collections_abc.Sequence, collections_abc.Iterator)
):
raise TypeError("json_rows argument should be a sequence of dicts")
# Convert table to just a reference because unlike insert_rows,
# insert_rows_json doesn't need the table schema. It's not doing any
Expand Down
15 changes: 13 additions & 2 deletions bigquery/tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5048,6 +5048,7 @@ def _row_data(row):
)

def test_insert_rows_errors(self):
from google.cloud.bigquery.schema import SchemaField
from google.cloud.bigquery.table import Table

ROWS = [
Expand All @@ -5058,6 +5059,7 @@ def test_insert_rows_errors(self):
]
creds = _make_credentials()
http = object()

client = self._make_one(project=self.PROJECT, credentials=creds, _http=http)

# table ref with no selected fields
Expand All @@ -5068,10 +5070,19 @@ def test_insert_rows_errors(self):
with self.assertRaises(ValueError):
client.insert_rows(Table(self.TABLE_REF), ROWS)

# neither Table nor tableReference
# neither Table nor TableReference
with self.assertRaises(TypeError):
client.insert_rows(1, ROWS)

schema = [
SchemaField("full_name", "STRING", mode="REQUIRED"),
]
table = Table(self.TABLE_REF, schema=schema)

# rows is just a dict
with self.assertRaises(TypeError):
client.insert_rows(table, {"full_name": "value"})

def test_insert_rows_w_numeric(self):
from google.cloud.bigquery import table
from google.cloud.bigquery.schema import SchemaField
Expand Down Expand Up @@ -5853,7 +5864,7 @@ def test_list_rows_error(self):
http = object()
client = self._make_one(project=self.PROJECT, credentials=creds, _http=http)

# neither Table nor tableReference
# neither Table nor TableReference
with self.assertRaises(TypeError):
client.list_rows(1)

Expand Down