diff --git a/google/cloud/bigquery/client.py b/google/cloud/bigquery/client.py index 11cceea42..00b9ad988 100644 --- a/google/cloud/bigquery/client.py +++ b/google/cloud/bigquery/client.py @@ -58,6 +58,7 @@ import google.api_core.client_options import google.api_core.exceptions as core_exceptions +from google.api_core.exceptions import NotFound from google.api_core.iam import Policy from google.api_core import page_iterator from google.api_core import retry as retries @@ -123,6 +124,7 @@ from google.cloud.bigquery.format_options import ParquetOptions from google.cloud.bigquery import _helpers + TimeoutType = Union[float, None] ResumableTimeoutType = Union[ None, float, Tuple[float, float] @@ -2831,8 +2833,15 @@ def load_table_from_json( new_job_config.source_format = job.SourceFormat.NEWLINE_DELIMITED_JSON - if new_job_config.schema is None: - new_job_config.autodetect = True + # make table id + # table_id = "your-project.your_dataset.your_table" + destination = _table_arg_to_table_ref(destination, default_project=self.project) + # check if table exists + try: + self.get_table(destination) # Make an API request. + job_config.autodetect = False + except NotFound: + job_config.autodetect = True if project is None: project = self.project @@ -2840,8 +2849,6 @@ def load_table_from_json( if location is None: location = self.location - destination = _table_arg_to_table_ref(destination, default_project=self.project) - data_str = "\n".join(json.dumps(item, ensure_ascii=False) for item in json_rows) encoded_str = data_str.encode() data_file = io.BytesIO(encoded_str) diff --git a/tests/system/test_client.py b/tests/system/test_client.py index 8fd532f4c..34a8037cb 100644 --- a/tests/system/test_client.py +++ b/tests/system/test_client.py @@ -864,8 +864,18 @@ def test_load_table_from_json_basic_use(self): ) json_rows = [ - {"name": "John", "age": 18, "birthday": "2001-10-15", "is_awesome": False}, - {"name": "Chuck", "age": 79, "birthday": "1940-03-10", "is_awesome": True}, + { + "name": "John", + "age": "18", + "birthday": "2001-10-15", + "is_awesome": False, + }, + { + "name": "Chuck", + "age": "79", + "birthday": "1940-03-10", + "is_awesome": True, + }, ] dataset_id = _make_dataset_id("bq_system_test") @@ -891,6 +901,64 @@ def test_load_table_from_json_basic_use(self): self.assertEqual(tuple(table.schema), table_schema) self.assertEqual(table.num_rows, 2) + def test_load_table_from_json_table_exists(self): + table_schema = (bigquery.SchemaField("age", "STRING", mode="REQUIRED"),) + json_rows = [ + { + "age": "18", + }, + { + "age": "79", + }, + ] + + dataset_id = _make_dataset_id("bq_system_test") + self.temp_dataset(dataset_id) + table_id = "{}.{}.load_table_from_json_bug_check_with_schema".format( + Config.CLIENT.project, dataset_id + ) + + # create an empty table + table = helpers.retry_403(Config.CLIENT.create_table)(Table(table_id)) + self.to_delete.insert(0, table) + + job_config = bigquery.LoadJobConfig(schema=table_schema) + load_job = Config.CLIENT.load_table_from_json( + json_rows, table_id, job_config=job_config + ) + load_job.result() + + table = Config.CLIENT.get_table(table) + fetched = self._fetch_single_page(table) + row_tuples = [r.values() for r in fetched] + assert type(table.schema[0].field_type) is str + assert type(row_tuples[0][0]) is str + + def test_load_table_from_json_bug_table_not_exists(self): + table_schema = (bigquery.SchemaField("age", "INTEGER", mode="NULLABLE"),) + json_rows = [ + { + "age": "18", + }, + { + "age": "79", + }, + ] + dataset_id = _make_dataset_id("bq_system_test") + self.temp_dataset(dataset_id) + table_id = "{}.{}.load_table_from_json_bug_check".format( + Config.CLIENT.project, dataset_id + ) + + job_config = bigquery.LoadJobConfig() + job_config.autodetect = True + load_job = Config.CLIENT.load_table_from_json(json_rows, table_id) + load_job.result() + + table = Config.CLIENT.get_table(table_id) + self.assertTrue(table.schema) + self.assertEqual(tuple(table.schema), table_schema) + def test_load_table_from_json_schema_autodetect(self): json_rows = [ {"name": "John", "age": 18, "birthday": "2001-10-15", "is_awesome": False}, diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index cf0aa4028..8474898a8 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -8699,8 +8699,8 @@ def test_load_table_from_json_basic_use(self): sent_config = load_table_from_file.mock_calls[0][2]["job_config"] assert sent_config.source_format == job.SourceFormat.NEWLINE_DELIMITED_JSON - assert sent_config.schema is None - assert sent_config.autodetect + # assert sent_config.schema is None + # assert sent_config.autodetect def test_load_table_from_json_non_default_args(self): from google.cloud.bigquery import job