Skip to content

Commit eda2451

Browse files
authored
feat: Redshift data api - allow all auth combinations (#2475)
* feat: Redshift data api - allow all auth combinations Signed-off-by: Anton Kukushkin <[email protected]> * Better error message Signed-off-by: Anton Kukushkin <[email protected]> * Formatting Signed-off-by: Anton Kukushkin <[email protected]> --------- Signed-off-by: Anton Kukushkin <[email protected]>
1 parent f7d8b93 commit eda2451

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

awswrangler/data_api/redshift.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,12 @@ def _validate_redshift_target(self) -> None:
9393
raise ValueError("Either `cluster_id` or `workgroup_name`(Redshift Serverless) must be set for connection")
9494

9595
def _validate_auth_method(self) -> None:
96-
if not self.workgroup_name and not self.secret_arn and not self.db_user:
97-
raise ValueError("Either `secret_arn` or `db_user` must be set for authentication")
96+
if not self.workgroup_name and not self.secret_arn and not self.db_user and not self.cluster_id:
97+
raise exceptions.InvalidArgumentCombination(
98+
"Either `secret_arn`, `workgroup_name`, `db_user`, or `cluster_id` must be set for authentication."
99+
)
100+
if self.db_user and self.secret_arn:
101+
raise exceptions.InvalidArgumentCombination("Only one of `secret_arn` or `db_user` is allowed.")
98102

99103
def _execute_statement(
100104
self,
@@ -110,26 +114,25 @@ def _execute_statement(
110114

111115
self._validate_redshift_target()
112116
self._validate_auth_method()
113-
credentials = {}
117+
args = {}
114118
if self.secret_arn:
115-
credentials = {"SecretArn": self.secret_arn}
116-
elif self.db_user:
117-
credentials = {"DbUser": self.db_user}
119+
args["SecretArn"] = self.secret_arn
120+
if self.db_user:
121+
args["DbUser"] = self.db_user
118122

119123
if database is None:
120124
database = self.database
121125

122126
if self.cluster_id:
123-
redshift_target = {"ClusterIdentifier": self.cluster_id}
124-
elif self.workgroup_name:
125-
redshift_target = {"WorkgroupName": self.workgroup_name}
127+
args["ClusterIdentifier"] = self.cluster_id
128+
if self.workgroup_name:
129+
args["WorkgroupName"] = self.workgroup_name
126130

127131
_logger.debug("Executing %s", sql)
128132
response = self.client.execute_statement(
129-
**redshift_target, # type: ignore[arg-type]
130133
Database=database,
131134
Sql=sql,
132-
**credentials, # type: ignore[arg-type]
135+
**args, # type: ignore[arg-type]
133136
)
134137
return response["Id"]
135138

tests/unit/test_data_api.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,23 @@ def test_connect_redshift_serverless_iam_role(databases_parameters: Dict[str, An
5454
assert df.shape == (1, 1)
5555

5656

57+
def test_connect_redshift_cluster_iam_role(databases_parameters: Dict[str, Any]) -> None:
58+
cluster_id = databases_parameters["redshift"]["identifier"]
59+
database = databases_parameters["redshift"]["database"]
60+
con = wr.data_api.redshift.connect(cluster_id=cluster_id, database=database, boto3_session=None)
61+
df = wr.data_api.redshift.read_sql_query("SELECT 1", con=con)
62+
assert df.shape == (1, 1)
63+
64+
65+
def test_connect_redshift_cluster_db_user(databases_parameters: Dict[str, Any]) -> None:
66+
cluster_id = databases_parameters["redshift"]["identifier"]
67+
database = databases_parameters["redshift"]["database"]
68+
db_user = databases_parameters["user"]
69+
con = wr.data_api.redshift.connect(cluster_id=cluster_id, database=database, db_user=db_user, boto3_session=None)
70+
df = wr.data_api.redshift.read_sql_query("SELECT 1", con=con)
71+
assert df.shape == (1, 1)
72+
73+
5774
def test_connect_redshift_serverless_secrets_manager(databases_parameters: Dict[str, Any]) -> None:
5875
workgroup_name = databases_parameters["redshift_serverless"]["workgroup"]
5976
database = databases_parameters["redshift_serverless"]["database"]

0 commit comments

Comments
 (0)