Skip to content

Commit ccf0ec2

Browse files
jbatswast
authored andcommitted
bigquery: add Client.list_rows, remove Table.fetch_data (#4119)
1 parent 33244cf commit ccf0ec2

File tree

5 files changed

+333
-355
lines changed

5 files changed

+333
-355
lines changed

bigquery/google/cloud/bigquery/client.py

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@
2626
from google.cloud.bigquery._http import Connection
2727
from google.cloud.bigquery.dataset import Dataset
2828
from google.cloud.bigquery.dataset import DatasetReference
29-
from google.cloud.bigquery.table import Table
29+
from google.cloud.bigquery.table import Table, _TABLE_HAS_NO_SCHEMA
3030
from google.cloud.bigquery.table import TableReference
3131
from google.cloud.bigquery.job import CopyJob
3232
from google.cloud.bigquery.job import ExtractJob
3333
from google.cloud.bigquery.job import LoadJob
3434
from google.cloud.bigquery.job import QueryJob
3535
from google.cloud.bigquery.job import QueryJobConfig
3636
from google.cloud.bigquery.query import QueryResults
37+
from google.cloud.bigquery._helpers import _item_to_row
38+
from google.cloud.bigquery._helpers import _rows_page_start
3739

3840

3941
class Project(object):
@@ -346,7 +348,6 @@ def delete_table(self, table):
346348
:type table: One of:
347349
:class:`~google.cloud.bigquery.table.Table`
348350
:class:`~google.cloud.bigquery.table.TableReference`
349-
350351
:param table: the table to delete, or a reference to it.
351352
"""
352353
if not isinstance(table, (Table, TableReference)):
@@ -667,6 +668,80 @@ def query_rows(self, query, job_config=None, job_id=None, timeout=None):
667668
job.begin()
668669
return job.result(timeout=timeout)
669670

671+
def list_rows(self, table, selected_fields=None, max_results=None,
672+
page_token=None, start_index=None):
673+
"""List the rows of the table.
674+
675+
See
676+
https://cloud.google.com/bigquery/docs/reference/rest/v2/tabledata/list
677+
678+
.. note::
679+
680+
This method assumes that the provided schema is up-to-date with the
681+
schema as defined on the back-end: if the two schemas are not
682+
identical, the values returned may be incomplete. To ensure that the
683+
local copy of the schema is up-to-date, call ``client.get_table``.
684+
685+
:type table: One of:
686+
:class:`~google.cloud.bigquery.table.Table`
687+
:class:`~google.cloud.bigquery.table.TableReference`
688+
:param table: the table to list, or a reference to it.
689+
690+
:type selected_fields: list of :class:`SchemaField`
691+
:param selected_fields:
692+
The fields to return. Required if ``table`` is a
693+
:class:`~google.cloud.bigquery.table.TableReference`.
694+
695+
:type max_results: int
696+
:param max_results: maximum number of rows to return.
697+
698+
:type page_token: str
699+
:param page_token: (Optional) Token representing a cursor into the
700+
table's rows.
701+
702+
:type start_index: int
703+
:param page_token: (Optional) The zero-based index of the starting
704+
row to read.
705+
706+
:rtype: :class:`~google.api.core.page_iterator.Iterator`
707+
:returns: Iterator of row data :class:`tuple`s. During each page, the
708+
iterator will have the ``total_rows`` attribute set,
709+
which counts the total number of rows **in the table**
710+
(this is distinct from the total number of rows in the
711+
current page: ``iterator.page.num_items``).
712+
713+
"""
714+
if selected_fields is not None:
715+
schema = selected_fields
716+
elif isinstance(table, TableReference):
717+
raise ValueError('need selected_fields with TableReference')
718+
elif isinstance(table, Table):
719+
if len(table._schema) == 0:
720+
raise ValueError(_TABLE_HAS_NO_SCHEMA)
721+
schema = table.schema
722+
else:
723+
raise TypeError('table should be Table or TableReference')
724+
725+
params = {}
726+
if selected_fields is not None:
727+
params['selectedFields'] = [f.name for f in selected_fields]
728+
if start_index is not None:
729+
params['startIndex'] = start_index
730+
731+
iterator = page_iterator.HTTPIterator(
732+
client=self,
733+
api_request=self._connection.api_request,
734+
path='%s/data' % (table.path,),
735+
item_to_value=_item_to_row,
736+
items_key='rows',
737+
page_token=page_token,
738+
next_token='pageToken',
739+
max_results=max_results,
740+
page_start=_rows_page_start,
741+
extra_params=params)
742+
iterator.schema = schema
743+
return iterator
744+
670745

671746
# pylint: disable=unused-argument
672747
def _item_to_project(iterator, resource):

bigquery/google/cloud/bigquery/table.py

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,10 @@
2525
from google.resumable_media.requests import MultipartUpload
2626
from google.resumable_media.requests import ResumableUpload
2727

28-
from google.api.core import page_iterator
2928
from google.cloud import exceptions
3029
from google.cloud._helpers import _datetime_from_microseconds
3130
from google.cloud._helpers import _millis_from_datetime
3231
from google.cloud.bigquery.schema import SchemaField
33-
from google.cloud.bigquery._helpers import _item_to_row
34-
from google.cloud.bigquery._helpers import _rows_page_start
3532
from google.cloud.bigquery._helpers import _SCALAR_VALUE_TO_JSON_ROW
3633

3734

@@ -768,61 +765,6 @@ def update(self, client=None):
768765
method='PUT', path=self.path, data=self._build_resource())
769766
self._set_properties(api_response)
770767

771-
def fetch_data(self, max_results=None, page_token=None, client=None):
772-
"""API call: fetch the table data via a GET request
773-
774-
See
775-
https://cloud.google.com/bigquery/docs/reference/rest/v2/tabledata/list
776-
777-
.. note::
778-
779-
This method assumes that its instance's ``schema`` attribute is
780-
up-to-date with the schema as defined on the back-end: if the
781-
two schemas are not identical, the values returned may be
782-
incomplete. To ensure that the local copy of the schema is
783-
up-to-date, call ``client.get_table``.
784-
785-
:type max_results: int
786-
:param max_results: (Optional) Maximum number of rows to return.
787-
788-
:type page_token: str
789-
:param page_token: (Optional) Token representing a cursor into the
790-
table's rows.
791-
792-
:type client: :class:`~google.cloud.bigquery.client.Client`
793-
:param client: (Optional) The client to use. If not passed, falls
794-
back to the ``client`` stored on the current dataset.
795-
796-
:rtype: :class:`~google.api.core.page_iterator.Iterator`
797-
:returns: Iterator of row data :class:`tuple`s. During each page, the
798-
iterator will have the ``total_rows`` attribute set,
799-
which counts the total number of rows **in the table**
800-
(this is distinct from the total number of rows in the
801-
current page: ``iterator.page.num_items``).
802-
"""
803-
if len(self._schema) == 0:
804-
raise ValueError(_TABLE_HAS_NO_SCHEMA)
805-
806-
params = {}
807-
808-
if max_results is not None:
809-
params['maxResults'] = max_results
810-
811-
client = self._require_client(client)
812-
path = '%s/data' % (self.path,)
813-
iterator = page_iterator.HTTPIterator(
814-
client=client,
815-
api_request=client._connection.api_request,
816-
path=path,
817-
item_to_value=_item_to_row,
818-
items_key='rows',
819-
page_token=page_token,
820-
page_start=_rows_page_start,
821-
next_token='pageToken',
822-
extra_params=params)
823-
iterator.schema = self._schema
824-
return iterator
825-
826768
def row_from_mapping(self, mapping):
827769
"""Convert a mapping to a row tuple using the schema.
828770

bigquery/tests/system.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ def test_update_table(self):
295295

296296
@staticmethod
297297
def _fetch_single_page(table):
298-
iterator = table.fetch_data()
298+
iterator = Config.CLIENT.list_rows(table)
299299
page = six.next(iterator.pages)
300300
return list(page)
301301

0 commit comments

Comments
 (0)