Skip to content
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
12 changes: 8 additions & 4 deletions bigquery/google/cloud/bigquery/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from google.cloud.client import ClientWithProject
from google.cloud.bigquery._http import Connection
from google.cloud.bigquery.dataset import Dataset
from google.cloud.bigquery.dataset import DatasetReference
from google.cloud.bigquery.job import CopyJob
from google.cloud.bigquery.job import ExtractJob
from google.cloud.bigquery.job import LoadJob
Expand Down Expand Up @@ -148,7 +149,7 @@ def list_datasets(self, include_all=False, max_results=None,
extra_params=extra_params)

def dataset(self, dataset_name, project=None):
"""Construct a dataset bound to this client.
"""Construct a reference to a dataset.

:type dataset_name: str
:param dataset_name: Name of the dataset.
Expand All @@ -157,10 +158,13 @@ def dataset(self, dataset_name, project=None):
:param project: (Optional) project ID for the dataset (defaults to
the project of the client).

:rtype: :class:`google.cloud.bigquery.dataset.Dataset`
:returns: a new ``Dataset`` instance
:rtype: :class:`google.cloud.bigquery.dataset.DatasetReference`
:returns: a new ``DatasetReference`` instance
"""
return Dataset(dataset_name, client=self, project=project)
if project is None:
project = self.project

return DatasetReference(project, dataset_name)

def _get_query_results(self, job_id, project=None, timeout_ms=None):
"""Get the query results object for a query job.
Expand Down
9 changes: 9 additions & 0 deletions bigquery/google/cloud/bigquery/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from google.cloud._helpers import _datetime_from_microseconds
from google.cloud.exceptions import NotFound
from google.cloud.bigquery.table import Table
from google.cloud.bigquery.table import TableReference


class AccessEntry(object):
Expand Down Expand Up @@ -126,6 +127,14 @@ def dataset_id(self):
"""
return self._dataset_id

def table(self, table_id):
"""Constructs a TableReference.

:rtype: :class:`google.cloud.bigquery.table.TableReference`
:returns: a TableReference for a table in this dataset.
"""
return TableReference(self, table_id)


class Dataset(object):
"""Datasets are containers for tables.
Expand Down
8 changes: 4 additions & 4 deletions bigquery/google/cloud/bigquery/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -1362,8 +1362,8 @@ def _copy_configuration_properties(self, configuration):
dest_local = self._destination_table_resource()
if dest_remote != dest_local:
project = dest_remote['projectId']
dataset = self._client.dataset(
dest_remote['datasetId'], project=project)
dataset = Dataset(
dest_remote['datasetId'], self._client, project=project)
self.destination = dataset.table(dest_remote['tableId'])

def_ds = configuration.get('defaultDataset')
Expand All @@ -1372,7 +1372,7 @@ def _copy_configuration_properties(self, configuration):
del self.default_dataset
else:
project = def_ds['projectId']
self.default_dataset = self._client.dataset(def_ds['datasetId'])
self.default_dataset = Dataset(def_ds['datasetId'], self._client)

udf_resources = []
for udf_mapping in configuration.get(self._UDF_KEY, ()):
Expand Down Expand Up @@ -1528,7 +1528,7 @@ def referenced_tables(self):
ds_name = table['datasetId']
t_dataset = datasets_by_project_name.get((t_project, ds_name))
if t_dataset is None:
t_dataset = client.dataset(ds_name, project=t_project)
t_dataset = Dataset(ds_name, client, project=t_project)
datasets_by_project_name[(t_project, ds_name)] = t_dataset

t_name = table['tableId']
Expand Down
36 changes: 36 additions & 0 deletions bigquery/google/cloud/bigquery/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,42 @@
_DEFAULT_NUM_RETRIES = 6


class TableReference(object):
"""TableReferences are pointers to tables.

See
https://cloud.google.com/bigquery/docs/reference/rest/v2/tables

:type dataset_ref: :class:`google.cloud.bigquery.dataset.DatasetReference`
:param dataset_ref: a pointer to the dataset

:type table_id: str
:param table_id: the ID of the table
"""

def __init__(self, dataset_ref, table_id):
self._dataset_ref = dataset_ref
self._table_id = table_id

@property
def dataset_ref(self):

This comment was marked as spam.

This comment was marked as spam.

"""Pointer to the dataset.

:rtype: :class:`google.cloud.bigquery.dataset.DatasetReference`
:returns: a pointer to the dataset.
"""
return self._dataset_ref

@property
def table_id(self):
"""Table ID.

:rtype: str
:returns: the table ID.
"""
return self._table_id


class Table(object):
"""Tables represent a set of rows whose values correspond to a schema.

Expand Down
55 changes: 28 additions & 27 deletions bigquery/tests/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import six

from google.cloud import bigquery
from google.cloud.bigquery.dataset import Dataset
from google.cloud._helpers import UTC
from google.cloud.bigquery import dbapi
from google.cloud.exceptions import Forbidden
Expand Down Expand Up @@ -111,7 +112,7 @@ def _still_in_use(bad_request):

def test_create_dataset(self):
DATASET_NAME = _make_dataset_name('create_dataset')
dataset = Config.CLIENT.dataset(DATASET_NAME)
dataset = Dataset(DATASET_NAME, Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand All @@ -122,20 +123,20 @@ def test_create_dataset(self):

def test_reload_dataset(self):
DATASET_NAME = _make_dataset_name('reload_dataset')
dataset = Config.CLIENT.dataset(DATASET_NAME)
dataset = Dataset(DATASET_NAME, Config.CLIENT)
dataset.friendly_name = 'Friendly'
dataset.description = 'Description'

retry_403(dataset.create)()
self.to_delete.append(dataset)

other = Config.CLIENT.dataset(DATASET_NAME)
other = Dataset(DATASET_NAME, Config.CLIENT)
other.reload()
self.assertEqual(other.friendly_name, 'Friendly')
self.assertEqual(other.description, 'Description')

def test_patch_dataset(self):
dataset = Config.CLIENT.dataset(_make_dataset_name('patch_dataset'))
dataset = Dataset(_make_dataset_name('patch_dataset'), Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand All @@ -149,7 +150,7 @@ def test_patch_dataset(self):
self.assertEqual(dataset.description, 'Description')

def test_update_dataset(self):
dataset = Config.CLIENT.dataset(_make_dataset_name('update_dataset'))
dataset = Dataset(_make_dataset_name('update_dataset'), Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand All @@ -175,7 +176,7 @@ def test_list_datasets(self):
'newest' + unique_resource_id(),
]
for dataset_name in datasets_to_create:
created_dataset = Config.CLIENT.dataset(dataset_name)
created_dataset = Dataset(dataset_name, Config.CLIENT)
retry_403(created_dataset.create)()
self.to_delete.append(created_dataset)

Expand All @@ -189,7 +190,7 @@ def test_list_datasets(self):
self.assertEqual(len(created), len(datasets_to_create))

def test_create_table(self):
dataset = Config.CLIENT.dataset(_make_dataset_name('create_table'))
dataset = Dataset(_make_dataset_name('create_table'), Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand All @@ -208,7 +209,7 @@ def test_create_table(self):

def test_list_tables(self):
DATASET_NAME = _make_dataset_name('list_tables')
dataset = Config.CLIENT.dataset(DATASET_NAME)
dataset = Dataset(DATASET_NAME, Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand Down Expand Up @@ -244,7 +245,7 @@ def test_list_tables(self):
self.assertEqual(len(created), len(tables_to_create))

def test_patch_table(self):
dataset = Config.CLIENT.dataset(_make_dataset_name('patch_table'))
dataset = Dataset(_make_dataset_name('patch_table'), Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand All @@ -266,7 +267,7 @@ def test_patch_table(self):
self.assertEqual(table.description, 'Description')

def test_update_table(self):
dataset = Config.CLIENT.dataset(_make_dataset_name('update_table'))
dataset = Dataset(_make_dataset_name('update_table'), Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand Down Expand Up @@ -309,8 +310,8 @@ def test_insert_data_then_dump_table(self):
('Bhettye Rhubble', 27, None),
]
ROW_IDS = range(len(ROWS))
dataset = Config.CLIENT.dataset(
_make_dataset_name('insert_data_then_dump'))
dataset = Dataset(
_make_dataset_name('insert_data_then_dump'), Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand Down Expand Up @@ -353,8 +354,8 @@ def test_load_table_from_local_file_then_dump_table(self):
]
TABLE_NAME = 'test_table'

dataset = Config.CLIENT.dataset(
_make_dataset_name('load_local_then_dump'))
dataset = Dataset(
_make_dataset_name('load_local_then_dump'), Config.CLIENT)

retry_403(dataset.create)()
self.to_delete.append(dataset)
Expand Down Expand Up @@ -402,8 +403,8 @@ def test_load_table_from_local_avro_file_then_dump_table(self):
("orange", 590),
("red", 650)]

dataset = Config.CLIENT.dataset(
_make_dataset_name('load_local_then_dump'))
dataset = Dataset(
_make_dataset_name('load_local_then_dump'), Config.CLIENT)

retry_403(dataset.create)()
self.to_delete.append(dataset)
Expand Down Expand Up @@ -466,8 +467,8 @@ def test_load_table_from_storage_then_dump_table(self):

self.to_delete.insert(0, blob)

dataset = Config.CLIENT.dataset(
_make_dataset_name('load_gcs_then_dump'))
dataset = Dataset(
_make_dataset_name('load_gcs_then_dump'), Config.CLIENT)

retry_403(dataset.create)()
self.to_delete.append(dataset)
Expand Down Expand Up @@ -536,8 +537,8 @@ def test_load_table_from_storage_w_autodetect_schema(self):

self.to_delete.insert(0, blob)

dataset = Config.CLIENT.dataset(
_make_dataset_name('load_gcs_then_dump'))
dataset = Dataset(
_make_dataset_name('load_gcs_then_dump'), Config.CLIENT)

retry_403(dataset.create)()
self.to_delete.append(dataset)
Expand Down Expand Up @@ -574,7 +575,7 @@ def test_job_cancel(self):
TABLE_NAME = 'test_table'
QUERY = 'SELECT * FROM %s.%s' % (DATASET_NAME, TABLE_NAME)

dataset = Config.CLIENT.dataset(DATASET_NAME)
dataset = Dataset(DATASET_NAME, Config.CLIENT)

retry_403(dataset.create)()
self.to_delete.append(dataset)
Expand Down Expand Up @@ -765,7 +766,7 @@ def test_dbapi_fetchall(self):
def _load_table_for_dml(self, rows, dataset_name, table_name):
from google.cloud._testing import _NamedTemporaryFile

dataset = Config.CLIENT.dataset(dataset_name)
dataset = Dataset(dataset_name, Config.CLIENT)
retry_403(dataset.create)()
self.to_delete.append(dataset)

Expand Down Expand Up @@ -1081,7 +1082,7 @@ def test_dump_table_w_public_data(self):
DATASET_NAME = 'samples'
TABLE_NAME = 'natality'

dataset = Config.CLIENT.dataset(DATASET_NAME, project=PUBLIC)
dataset = Dataset(DATASET_NAME, Config.CLIENT, project=PUBLIC)
table = dataset.table(TABLE_NAME)
# Reload table to get the schema before fetching the rows.
table.reload()
Expand Down Expand Up @@ -1134,8 +1135,8 @@ def test_insert_nested_nested(self):
('Some value', record)
]
table_name = 'test_table'
dataset = Config.CLIENT.dataset(
_make_dataset_name('issue_2951'))
dataset = Dataset(
_make_dataset_name('issue_2951'), Config.CLIENT)

retry_403(dataset.create)()
self.to_delete.append(dataset)
Expand All @@ -1154,8 +1155,8 @@ def test_insert_nested_nested(self):
def test_create_table_insert_fetch_nested_schema(self):

table_name = 'test_table'
dataset = Config.CLIENT.dataset(
_make_dataset_name('create_table_nested_schema'))
dataset = Dataset(
_make_dataset_name('create_table_nested_schema'), Config.CLIENT)
self.assertFalse(dataset.exists())

retry_403(dataset.create)()
Expand Down
23 changes: 18 additions & 5 deletions bigquery/tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,31 @@ def test_list_datasets_explicit_response_missing_datasets_key(self):
self.assertEqual(req['query_params'],
{'all': True, 'maxResults': 3, 'pageToken': TOKEN})

def test_dataset(self):
from google.cloud.bigquery.dataset import Dataset
def test_dataset_with_specified_project(self):
from google.cloud.bigquery.dataset import DatasetReference

PROJECT = 'PROJECT'
DATASET = 'dataset_name'
creds = _make_credentials()
http = object()
client = self._make_one(project=PROJECT, credentials=creds, _http=http)
dataset = client.dataset(DATASET, PROJECT)
self.assertIsInstance(dataset, DatasetReference)
self.assertEqual(dataset.dataset_id, DATASET)
self.assertEqual(dataset.project_id, PROJECT)

def test_dataset_with_default_project(self):
from google.cloud.bigquery.dataset import DatasetReference

PROJECT = 'PROJECT'
DATASET = 'dataset_name'
creds = _make_credentials()
http = object()
client = self._make_one(project=PROJECT, credentials=creds, _http=http)
dataset = client.dataset(DATASET)
self.assertIsInstance(dataset, Dataset)
self.assertEqual(dataset.name, DATASET)
self.assertIs(dataset._client, client)
self.assertIsInstance(dataset, DatasetReference)
self.assertEqual(dataset.dataset_id, DATASET)
self.assertEqual(dataset.project_id, PROJECT)

def test_job_from_resource_unknown_type(self):
PROJECT = 'PROJECT'
Expand Down
6 changes: 6 additions & 0 deletions bigquery/tests/unit/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ def test_ctor_defaults(self):
self.assertEqual(dataset_ref.project_id, 'some-project-1')
self.assertEqual(dataset_ref.dataset_id, 'dataset_1')

def test_table(self):
dataset_ref = self._make_one('some-project-1', 'dataset_1')
table_ref = dataset_ref.table('table_1')
self.assertIs(table_ref.dataset_ref, dataset_ref)
self.assertEqual(table_ref.table_id, 'table_1')


class TestDataset(unittest.TestCase):
PROJECT = 'project'
Expand Down
5 changes: 0 additions & 5 deletions bigquery/tests/unit/test_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -2697,11 +2697,6 @@ def __init__(self, project='project', connection=None):
self.project = project
self._connection = connection

def dataset(self, name, project=None):
from google.cloud.bigquery.dataset import Dataset

return Dataset(name, client=self, project=project)

def _get_query_results(self, job_id):
from google.cloud.bigquery.query import QueryResults

Expand Down
Loading