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

BigQuery: replaces table.create() with client.create_table() #4038

Merged
merged 5 commits into from
Sep 22, 2017
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
18 changes: 18 additions & 0 deletions bigquery/google/cloud/bigquery/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,24 @@ def create_dataset(self, dataset):
method='POST', path=path, data=dataset._build_resource())
return Dataset.from_api_repr(api_response)

def create_table(self, table):
"""API call: create a table via a PUT request

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

:type table: :class:`~google.cloud.bigquery.table.Table`
:param table: A ``Table`` populated with the desired initial state.

:rtype: ":class:`~google.cloud.bigquery.table.Table`"
:returns: a new ``Table`` returned from the service.
"""
path = '/projects/%s/datasets/%s/tables' % (
table.project, table.dataset_id)
api_response = self._connection.api_request(
method='POST', path=path, data=table._build_resource())
return Table.from_api_repr(api_response, self)

def get_dataset(self, dataset_ref):
"""Fetch the dataset referenced by ``dataset_ref``

Expand Down
18 changes: 0 additions & 18 deletions bigquery/google/cloud/bigquery/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,24 +596,6 @@ def _build_resource(self):

return resource

def create(self, client=None):
"""API call: create the table via a PUT request

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

:type client: :class:`~google.cloud.bigquery.client.Client` or
``NoneType``
:param client: the client to use. If not passed, falls back to the
``client`` stored on the current dataset.
"""
client = self._require_client(client)
path = '/projects/%s/datasets/%s/tables' % (
self._project, self._dataset_id)
api_response = client._connection.api_request(
method='POST', path=path, data=self._build_resource())
self._set_properties(api_response)

def exists(self, client=None):
"""API call: test for the existence of the table via a GET request

Expand Down
83 changes: 42 additions & 41 deletions bigquery/tests/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,18 +180,19 @@ def test_list_datasets(self):

def test_create_table(self):
dataset = self.temp_dataset(_make_dataset_id('create_table'))

TABLE_NAME = 'test_table'
table_id = 'test_table'
full_name = bigquery.SchemaField('full_name', 'STRING',
mode='REQUIRED')
age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED')
table = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
self.assertFalse(table.exists())
table.create()
table_arg = Table(dataset.table(table_id), schema=[full_name, age],
client=Config.CLIENT)
self.assertFalse(table_arg.exists())

table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)

self.assertTrue(table.exists())
self.assertEqual(table.table_id, TABLE_NAME)
self.assertEqual(table.table_id, table_id)

def test_get_table_w_public_dataset(self):
PUBLIC = 'bigquery-public-data'
Expand Down Expand Up @@ -227,10 +228,10 @@ def test_list_dataset_tables(self):
mode='REQUIRED')
age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED')
for table_name in tables_to_create:
created_table = Table(dataset.table(table_name),
schema=[full_name, age],
client=Config.CLIENT)
created_table.create()
table = Table(dataset.table(table_name),
schema=[full_name, age],
client=Config.CLIENT)
created_table = retry_403(Config.CLIENT.create_table)(table)
self.to_delete.insert(0, created_table)

# Retrieve the tables.
Expand All @@ -249,10 +250,10 @@ def test_patch_table(self):
full_name = bigquery.SchemaField('full_name', 'STRING',
mode='REQUIRED')
age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED')
table = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
self.assertFalse(table.exists())
table.create()
table_arg = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
self.assertFalse(table_arg.exists())
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)
self.assertTrue(table.exists())
self.assertIsNone(table.friendly_name)
Expand All @@ -268,10 +269,10 @@ def test_update_table(self):
full_name = bigquery.SchemaField('full_name', 'STRING',
mode='REQUIRED')
age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED')
table = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
self.assertFalse(table.exists())
table.create()
table_arg = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
self.assertFalse(table_arg.exists())
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)
self.assertTrue(table.exists())
voter = bigquery.SchemaField('voter', 'BOOLEAN', mode='NULLABLE')
Expand Down Expand Up @@ -309,10 +310,10 @@ def test_insert_data_then_dump_table(self):
mode='REQUIRED')
age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED')
now = bigquery.SchemaField('now', 'TIMESTAMP')
table = Table(dataset.table(TABLE_NAME), schema=[full_name, age, now],
client=Config.CLIENT)
self.assertFalse(table.exists())
table.create()
table_arg = Table(dataset.table(TABLE_NAME),
schema=[full_name, age, now], client=Config.CLIENT)
self.assertFalse(table_arg.exists())
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)
self.assertTrue(table.exists())

Expand Down Expand Up @@ -346,9 +347,9 @@ def test_load_table_from_local_file_then_dump_table(self):
full_name = bigquery.SchemaField('full_name', 'STRING',
mode='REQUIRED')
age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED')
table = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
table.create()
table_arg = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)

with _NamedTemporaryFile() as temp:
Expand Down Expand Up @@ -450,9 +451,9 @@ def test_load_table_from_storage_then_dump_table(self):
full_name = bigquery.SchemaField('full_name', 'STRING',
mode='REQUIRED')
age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED')
table = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
table.create()
table_arg = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)

job = Config.CLIENT.load_table_from_storage(
Expand Down Expand Up @@ -652,9 +653,9 @@ def test_job_cancel(self):
full_name = bigquery.SchemaField('full_name', 'STRING',
mode='REQUIRED')
age = bigquery.SchemaField('age', 'INTEGER', mode='REQUIRED')
table = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
table.create()
table_arg = Table(dataset.table(TABLE_NAME), schema=[full_name, age],
client=Config.CLIENT)
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)

job = Config.CLIENT.run_async_query(JOB_NAME, QUERY)
Expand Down Expand Up @@ -839,9 +840,9 @@ def _load_table_for_dml(self, rows, dataset_id, table_id):
dataset = self.temp_dataset(dataset_id)
greeting = bigquery.SchemaField(
'greeting', 'STRING', mode='NULLABLE')
table = Table(dataset.table(table_id), schema=[greeting],
client=Config.CLIENT)
table.create()
table_arg = Table(dataset.table(table_id), schema=[greeting],
client=Config.CLIENT)
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)

with _NamedTemporaryFile() as temp:
Expand Down Expand Up @@ -1210,9 +1211,9 @@ def test_insert_nested_nested(self):
]
table_name = 'test_table'
dataset = self.temp_dataset(_make_dataset_id('issue_2951'))
table = Table(dataset.table(table_name), schema=schema,
client=Config.CLIENT)
table.create()
table_arg = Table(dataset.table(table_name), schema=schema,
client=Config.CLIENT)
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)

table.insert_data(to_insert)
Expand All @@ -1227,9 +1228,9 @@ def test_create_table_insert_fetch_nested_schema(self):
dataset = self.temp_dataset(
_make_dataset_id('create_table_nested_schema'))
schema = _load_json_schema()
table = Table(dataset.table(table_name), schema=schema,
client=Config.CLIENT)
table.create()
table_arg = Table(dataset.table(table_name), schema=schema,
client=Config.CLIENT)
table = retry_403(Config.CLIENT.create_table)(table_arg)
self.to_delete.insert(0, table)
self.assertTrue(table.exists())
self.assertEqual(table.table_id, table_name)
Expand Down
145 changes: 145 additions & 0 deletions bigquery/tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,151 @@ def test_create_dataset_w_attrs(self):
self.assertEqual(ds.default_table_expiration_ms, 3600)
self.assertEqual(ds.labels, LABELS)

def test_create_table_w_day_partition(self):
from google.cloud.bigquery.table import Table

project = 'PROJECT'
dataset_id = 'dataset_id'
table_id = 'table-id'
path = 'projects/%s/datasets/%s/tables' % (
project, dataset_id)
creds = _make_credentials()
client = self._make_one(project=project, credentials=creds)
resource = {
'id': '%s:%s:%s' % (project, dataset_id, table_id),
'tableReference': {
'projectId': project,
'datasetId': dataset_id,
'tableId': table_id
},
}
conn = client._connection = _Connection(resource)
table_ref = client.dataset(dataset_id).table(table_id)
table = Table(table_ref, client=client)
table.partitioning_type = 'DAY'

got = client.create_table(table)

self.assertEqual(len(conn._requested), 1)
req = conn._requested[0]
self.assertEqual(req['method'], 'POST')
self.assertEqual(req['path'], '/%s' % path)
sent = {
'tableReference': {
'projectId': project,
'datasetId': dataset_id,
'tableId': table_id
},
'timePartitioning': {'type': 'DAY'},
}
self.assertEqual(req['data'], sent)
self.assertEqual(table.partitioning_type, "DAY")
self.assertEqual(got.table_id, table_id)

def test_create_table_w_day_partition_and_expire(self):
from google.cloud.bigquery.table import Table

project = 'PROJECT'
dataset_id = 'dataset_id'
table_id = 'table-id'
path = 'projects/%s/datasets/%s/tables' % (
project, dataset_id)
creds = _make_credentials()
client = self._make_one(project=project, credentials=creds)
resource = {
'id': '%s:%s:%s' % (project, dataset_id, table_id),
'tableReference': {
'projectId': project,
'datasetId': dataset_id,
'tableId': table_id
},
}
conn = client._connection = _Connection(resource)
table_ref = client.dataset(dataset_id).table(table_id)
table = Table(table_ref, client=client)
table.partitioning_type = 'DAY'
table.partition_expiration = 100

got = client.create_table(table)

self.assertEqual(len(conn._requested), 1)
req = conn._requested[0]
self.assertEqual(req['method'], 'POST')
self.assertEqual(req['path'], '/%s' % path)
sent = {
'tableReference': {
'projectId': project,
'datasetId': dataset_id,
'tableId': table_id
},
'timePartitioning': {'type': 'DAY', 'expirationMs': 100},
}
self.assertEqual(req['data'], sent)
self.assertEqual(table.partitioning_type, "DAY")
self.assertEqual(table.partition_expiration, 100)
self.assertEqual(got.table_id, table_id)

def test_create_table_w_schema_and_query(self):
from google.cloud.bigquery.table import Table, SchemaField

project = 'PROJECT'
dataset_id = 'dataset_id'
table_id = 'table-id'
path = 'projects/%s/datasets/%s/tables' % (
project, dataset_id)
query = 'SELECT * from %s:%s' % (dataset_id, table_id)
creds = _make_credentials()
client = self._make_one(project=project, credentials=creds)
resource = {
'id': '%s:%s:%s' % (project, dataset_id, table_id),
'tableReference': {
'projectId': project,
'datasetId': dataset_id,
'tableId': table_id
},
'schema': {'fields': [
{'name': 'full_name', 'type': 'STRING', 'mode': 'REQUIRED'},
{'name': 'age', 'type': 'INTEGER', 'mode': 'REQUIRED'}]
},
'view': {
'query': query,
'useLegacySql': True
},
}
schema = [
SchemaField('full_name', 'STRING', mode='REQUIRED'),
SchemaField('age', 'INTEGER', mode='REQUIRED')
]
conn = client._connection = _Connection(resource)
table_ref = client.dataset(dataset_id).table(table_id)
table = Table(table_ref, schema=schema, client=client)
table.view_query = query

got = client.create_table(table)

self.assertEqual(len(conn._requested), 1)
req = conn._requested[0]
self.assertEqual(req['method'], 'POST')
self.assertEqual(req['path'], '/%s' % path)
sent = {
'tableReference': {
'projectId': project,
'datasetId': dataset_id,
'tableId': table_id
},
'schema': {'fields': [
{'name': 'full_name', 'type': 'STRING', 'mode': 'REQUIRED'},
{'name': 'age', 'type': 'INTEGER', 'mode': 'REQUIRED'}]
},
'view': {'query': query},
}
self.assertEqual(req['data'], sent)
self.assertEqual(got.table_id, table_id)
self.assertEqual(got.project, project)
self.assertEqual(got.dataset_id, dataset_id)
self.assertEqual(got.schema, schema)
self.assertEqual(got.view_query, query)

def test_get_table(self):
project = 'PROJECT'
dataset_id = 'dataset_id'
Expand Down
Loading