Skip to content

Commit 7e522ee

Browse files
authored
feat: support load job option ColumnNameCharacterMap (#1952)
* feat: support load job option ColumnNameCharacterMap * add unit test
1 parent 5d10f1e commit 7e522ee

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

google/cloud/bigquery/job/load.py

+41
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,26 @@
3232
from google.cloud.bigquery.query import ConnectionProperty
3333

3434

35+
class ColumnNameCharacterMap:
36+
"""Indicates the character map used for column names.
37+
38+
https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#columnnamecharactermap
39+
"""
40+
41+
COLUMN_NAME_CHARACTER_MAP_UNSPECIFIED = "COLUMN_NAME_CHARACTER_MAP_UNSPECIFIED"
42+
"""Unspecified column name character map."""
43+
44+
STRICT = "STRICT"
45+
"""Support flexible column name and reject invalid column names."""
46+
47+
V1 = "V1"
48+
""" Support alphanumeric + underscore characters and names must start with
49+
a letter or underscore. Invalid column names will be normalized."""
50+
51+
V2 = "V2"
52+
"""Support flexible column name. Invalid column names will be normalized."""
53+
54+
3555
class LoadJobConfig(_JobConfig):
3656
"""Configuration options for load jobs.
3757
@@ -597,6 +617,27 @@ def parquet_options(self, value):
597617
else:
598618
self._del_sub_prop("parquetOptions")
599619

620+
@property
621+
def column_name_character_map(self) -> str:
622+
"""Optional[google.cloud.bigquery.job.ColumnNameCharacterMap]:
623+
Character map supported for column names in CSV/Parquet loads. Defaults
624+
to STRICT and can be overridden by Project Config Service. Using this
625+
option with unsupported load formats will result in an error.
626+
627+
See
628+
https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationLoad.FIELDS.column_name_character_map
629+
"""
630+
return self._get_sub_prop(
631+
"columnNameCharacterMap",
632+
ColumnNameCharacterMap.COLUMN_NAME_CHARACTER_MAP_UNSPECIFIED,
633+
)
634+
635+
@column_name_character_map.setter
636+
def column_name_character_map(self, value: Optional[str]):
637+
if value is None:
638+
value = ColumnNameCharacterMap.COLUMN_NAME_CHARACTER_MAP_UNSPECIFIED
639+
self._set_sub_prop("columnNameCharacterMap", value)
640+
600641

601642
class LoadJob(_AsyncJob):
602643
"""Asynchronous job for loading data into a table.

tests/unit/job/test_load_config.py

+39
Original file line numberDiff line numberDiff line change
@@ -843,3 +843,42 @@ def test_parquet_options_setter_clearing(self):
843843

844844
config.parquet_options = None
845845
self.assertNotIn("parquetOptions", config._properties["load"])
846+
847+
def test_column_name_character_map_missing(self):
848+
from google.cloud.bigquery.job.load import ColumnNameCharacterMap
849+
850+
config = self._get_target_class()()
851+
self.assertEqual(
852+
config.column_name_character_map,
853+
ColumnNameCharacterMap.COLUMN_NAME_CHARACTER_MAP_UNSPECIFIED,
854+
)
855+
856+
def test_column_name_character_map_hit(self):
857+
from google.cloud.bigquery.job.load import ColumnNameCharacterMap
858+
859+
config = self._get_target_class()()
860+
config._properties["load"]["columnNameCharacterMap"] = "STRICT"
861+
self.assertEqual(
862+
config.column_name_character_map,
863+
ColumnNameCharacterMap.STRICT,
864+
)
865+
866+
def test_column_name_character_map_setter(self):
867+
from google.cloud.bigquery.job.load import ColumnNameCharacterMap
868+
869+
config = self._get_target_class()()
870+
config.column_name_character_map = "V1"
871+
self.assertEqual(
872+
config._properties["load"]["columnNameCharacterMap"],
873+
ColumnNameCharacterMap.V1,
874+
)
875+
876+
def test_column_name_character_map_none(self):
877+
from google.cloud.bigquery.job.load import ColumnNameCharacterMap
878+
879+
config = self._get_target_class()()
880+
config.column_name_character_map = None
881+
self.assertEqual(
882+
config._properties["load"]["columnNameCharacterMap"],
883+
ColumnNameCharacterMap.COLUMN_NAME_CHARACTER_MAP_UNSPECIFIED,
884+
)

0 commit comments

Comments
 (0)