Repository: googleapis/python-bigquery

Issue:
Support jsonExtension in LoadJobConfig
This would allow running the equivalent to:
```
bq load --source_format=NEWLINE_DELIMITED_JSON --json_extension=GEOJSON  <some>.<table>  <some_geojson_path>
```


Discussion:
Adding some notes for myself (and anyone who wants to tackle this):

Would need to take a look at LoadJobConfig and determine:
* Is this the right place to make these additions?
* What are the exact changes needed to add this feature?
* What tests need to be added to support testing of the new feature

I can't answer all your questions, but this workaround accomplishes what I want:
```
job_config = bigquery.LoadJobConfig(..., ..., ...)
job_config._set_sub_prop('jsonExtension', 'GEOJSON')
```
@bkanuka thanks for this additional context.

Resolving patch:
diff --git a/google/cloud/bigquery/job/load.py b/google/cloud/bigquery/job/load.py
--- a/google/cloud/bigquery/job/load.py
+++ b/google/cloud/bigquery/job/load.py
@@ -327,6 +327,19 @@ def ignore_unknown_values(self):
     def ignore_unknown_values(self, value):
         self._set_sub_prop("ignoreUnknownValues", value)
 
+    @property
+    def json_extension(self):
+        """Optional[str]: The extension to use for writing JSON data to BigQuery. Only supports GeoJSON currently.
+
+        See: https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationLoad.FIELDS.json_extension
+
+        """
+        return self._get_sub_prop("jsonExtension")
+
+    @json_extension.setter
+    def json_extension(self, value):
+        self._set_sub_prop("jsonExtension", value)
+
     @property
     def max_bad_records(self):
         """Optional[int]: Number of invalid rows to ignore.


Test patch:
diff --git a/tests/unit/job/test_load_config.py b/tests/unit/job/test_load_config.py
--- a/tests/unit/job/test_load_config.py
+++ b/tests/unit/job/test_load_config.py
@@ -413,6 +413,29 @@ def test_ignore_unknown_values_setter(self):
         config.ignore_unknown_values = True
         self.assertTrue(config._properties["load"]["ignoreUnknownValues"])
 
+    def test_json_extension_missing(self):
+        config = self._get_target_class()()
+        self.assertIsNone(config.json_extension)
+
+    def test_json_extension_hit(self):
+        config = self._get_target_class()()
+        config._properties["load"]["jsonExtension"] = "GEOJSON"
+        self.assertEqual(config.json_extension, "GEOJSON")
+
+    def test_json_extension_setter(self):
+        config = self._get_target_class()()
+        self.assertFalse(config.json_extension)
+        config.json_extension = "GEOJSON"
+        self.assertTrue(config.json_extension)
+        self.assertEqual(config._properties["load"]["jsonExtension"], "GEOJSON")
+
+    def test_to_api_repr_includes_json_extension(self):
+        config = self._get_target_class()()
+        config._properties["load"]["jsonExtension"] = "GEOJSON"
+        api_repr = config.to_api_repr()
+        self.assertIn("jsonExtension", api_repr["load"])
+        self.assertEqual(api_repr["load"]["jsonExtension"], "GEOJSON")
+
     def test_max_bad_records_missing(self):
         config = self._get_target_class()()
         self.assertIsNone(config.max_bad_records)