Skip to content
Closed
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
27 changes: 27 additions & 0 deletions google/cloud/bigquery/job/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,33 @@ def __setattr__(self, name, value):
)
super(_JobConfig, self).__setattr__(name, value)

@property
def job_timeout_ms(self):
""" Optional parameter. Job timeout in milliseconds. If this time limit is exceeded, BigQuery might attempt to stop the job.

https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfiguration.FIELDS.job_timeout_ms

e.g.
job_config = bigquery.QueryJobConfig( job_timeout_ms = 5000 )

or

job_config.job_timeout_ms = 5000
Raises:
ValueError: If ``value`` type is invalid.
"""

# None as this is an optional parameter.
Copy link
Contributor

Choose a reason for hiding this comment

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

It could be None, but it could also be a real integer value. We should return self._properties.get("jobTimeoutMs") (converted to an integer if not None. I believe there are other integer properties that use a helper function for this conversion.)

return None

@job_timeout_ms.setter
def jobtimeout(self, value):
Copy link
Contributor

Choose a reason for hiding this comment

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

Make sure this function name matches your @property.

if not isinstance(value, int):
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also allow None.

raise ValueError("Pass an int for jobTimeoutMs, e.g. 5000")

""" Docs indicate a string is expected by the API """
self._properties["jobTimeoutMs"] = str(value)

@property
def labels(self):
"""Dict[str, str]: Labels for the job.
Expand Down
37 changes: 34 additions & 3 deletions google/cloud/bigquery/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from google.cloud.bigquery import _helpers
from google.cloud.bigquery import standard_sql
from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration
import google.cloud.bigquery.model
Copy link
Contributor

Choose a reason for hiding this comment

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

We can revert the changes in this file.



class Model:
Expand Down Expand Up @@ -167,9 +168,23 @@ def training_runs(self) -> Sequence[Dict[str, Any]]:

Read-only.
"""

return typing.cast(
Sequence[Dict[str, Any]], self._properties.get("trainingRuns", [])
)

@property
def transform_columns(self) -> Sequence[Dict[str, Any]]:

"""
Output only. This field will be populated if a TRANSFORM clause was used to train a model. TRANSFORM clause (if used) takes featureColumns as input and outputs transformColumns. transformColumns then are used to train the model.
https://cloud.google.com/bigquery/docs/reference/rest/v2/models#Model.FIELDS.transform_columns
Read-only.
"""

return self._properties.get("transformColumns", [])



@property
def feature_columns(self) -> Sequence[standard_sql.StandardSqlField]:
Expand Down Expand Up @@ -258,7 +273,7 @@ def friendly_name(self, value: Optional[str]):
# TODO: Consider using typing.TypedDict when only Python 3.8+ is supported.
self._properties["friendlyName"] = value # type: ignore

@property
# @property
def labels(self) -> Dict[str, str]:
"""Labels for the table.

Expand All @@ -268,8 +283,8 @@ def labels(self) -> Dict[str, str]:
"""
return self._properties.setdefault("labels", {})

@labels.setter
def labels(self, value: Optional[Dict[str, str]]):
# @labels.setter
def set_labels(self, value: Optional[Dict[str, str]]):
if value is None:
value = {}
self._properties["labels"] = value
Expand Down Expand Up @@ -433,6 +448,20 @@ def __repr__(self):
self.project, self.dataset_id, self.model_id
)

class TransformColumn:
"""
"""

def __init__(self, resource:Dict[str, Any]):
self._properties = resource
self.name = resource.get("name")
not_resourced = resource.get("type")
if not_resourced is None:
self.type_ = None
else:
self.type_= standard_sql.StandardSqlDataType.from_api_repr(not_resourced)
self.transform_sql = resource.get("transformSQL")


def _model_arg_to_model_ref(value, default_project=None):
"""Helper to convert a string or Model to ModelReference.
Expand All @@ -444,3 +473,5 @@ def _model_arg_to_model_ref(value, default_project=None):
if isinstance(value, Model):
return value.reference
return value


5 changes: 5 additions & 0 deletions tests/unit/job/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ def test_ctor_defaults(self):
self.assertIsNone(job.destination_encryption_configuration)
self.assertIsNone(job.range_partitioning)
self.assertIsNone(job.time_partitioning)
self.assertIsNone(job.timeout_ms)
self.assertIsNone(job.clustering_fields)
self.assertIsNone(job.schema_update_options)

Expand Down Expand Up @@ -689,6 +690,10 @@ def test_ddl_target_table(self):
self.assertEqual(job.ddl_target_table.dataset_id, "ddl_ds")
self.assertEqual(job.ddl_target_table.project, self.PROJECT)

def test_jobtimeout_ms(self):
self.assertIsInstance(job.timeout_ms, value)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's set the job configuration timeout ms to something before asserting the value.

Copy link
Contributor

Choose a reason for hiding this comment

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

self.assertEquals(job.value.int)

def test_num_dml_affected_rows(self):
num_rows = 1234
client = _make_client(project=self.PROJECT)
Expand Down
7 changes: 4 additions & 3 deletions tests/unit/model/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,9 @@ def test_set_labels(object_under_test):


def test_replace_labels(object_under_test):
assert object_under_test.labels == {}
object_under_test.labels = {"data_owner": "someteam"}
assert object_under_test.labels == {"data_owner": "someteam"}
assert object_under_test.labels() =={}
Copy link
Contributor

Choose a reason for hiding this comment

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

Revert these changes.

object_under_test.set_labels({"data_owner": "someteam"})
assert object_under_test.labels() == {"data_owner": "someteam"}
labels = {}
object_under_test.labels = labels
assert object_under_test.labels is labels
Expand Down Expand Up @@ -380,6 +380,7 @@ def test_repr(target_class):
)



def test_to_api_repr(target_class):
model = target_class("my-proj.my_dset.my_model")
resource = {
Expand Down