|
3 | 3 | import re
|
4 | 4 | import boto3.session
|
5 | 5 | from botocore.exceptions import ClientError
|
6 |
| -from typing import Optional |
| 6 | +from typing import Optional, List |
7 | 7 |
|
8 |
| -from dbt.adapters.base import available |
| 8 | +from dbt.adapters.base import available, Column |
9 | 9 | from dbt.adapters.sql import SQLAdapter
|
10 | 10 | from dbt.adapters.athena import AthenaConnectionManager
|
11 | 11 | from dbt.adapters.athena.relation import AthenaRelation
|
12 | 12 | from dbt.events import AdapterLogger
|
| 13 | +from dbt.contracts.relation import RelationType |
13 | 14 | logger = AdapterLogger("Athena")
|
14 | 15 |
|
15 | 16 | class AthenaAdapter(SQLAdapter):
|
@@ -170,3 +171,63 @@ def quote_seed_column(
|
170 | 171 | self, column: str, quote_config: Optional[bool]
|
171 | 172 | ) -> str:
|
172 | 173 | return super().quote_seed_column(column, False)
|
| 174 | + |
| 175 | + def get_columns_in_relation(self, relation: AthenaRelation) -> List[Column]: |
| 176 | + conn = self.connections.get_thread_connection() |
| 177 | + creds = conn.credentials |
| 178 | + session = boto3.session.Session(region_name=creds.region_name, profile_name=creds.aws_profile_name) |
| 179 | + glue_client = session.client('glue') |
| 180 | + |
| 181 | + table = glue_client.get_table(DatabaseName=relation.schema, Name=relation.identifier) |
| 182 | + return [Column(c["Name"], c["Type"]) for c in table["Table"]["StorageDescriptor"]["Columns"] + table["Table"]["PartitionKeys"]] |
| 183 | + |
| 184 | + def list_schemas(self, database: str) -> List[str]: |
| 185 | + conn = self.connections.get_thread_connection() |
| 186 | + creds = conn.credentials |
| 187 | + session = boto3.session.Session(region_name=creds.region_name, profile_name=creds.aws_profile_name) |
| 188 | + glue_client = session.client('glue') |
| 189 | + paginator = glue_client.get_paginator("get_databases") |
| 190 | + |
| 191 | + result = [] |
| 192 | + logger.debug("CALL glue.get_databases()") |
| 193 | + for page in paginator.paginate(): |
| 194 | + for db in page["DatabaseList"]: |
| 195 | + result.append(db["Name"]) |
| 196 | + return result |
| 197 | + |
| 198 | + def list_relations_without_caching(self, schema_relation: AthenaRelation) -> List[AthenaRelation]: |
| 199 | + conn = self.connections.get_thread_connection() |
| 200 | + creds = conn.credentials |
| 201 | + session = boto3.session.Session(region_name=creds.region_name, profile_name=creds.aws_profile_name) |
| 202 | + glue_client = session.client('glue') |
| 203 | + paginator = glue_client.get_paginator("get_tables") |
| 204 | + |
| 205 | + result = [] |
| 206 | + logger.debug("CALL glue.get_tables('{}')", schema_relation.schema) |
| 207 | + for page in paginator.paginate(DatabaseName=schema_relation.schema): |
| 208 | + for table in page["TableList"]: |
| 209 | + if table["TableType"] == "EXTERNAL_TABLE": |
| 210 | + table_type = RelationType.Table |
| 211 | + elif table["TableType"] == "VIRTUAL_VIEW": |
| 212 | + table_type = RelationType.View |
| 213 | + else: |
| 214 | + raise ValueError(f"Unknown TableType for {table['Name']}: {table['TableType']}") |
| 215 | + rel = AthenaRelation.create(schema=table["DatabaseName"], identifier=table["Name"], database=schema_relation.database, type=table_type) |
| 216 | + result.append(rel) |
| 217 | + |
| 218 | + return result |
| 219 | + |
| 220 | + def drop_relation(self, relation: AthenaRelation): |
| 221 | + conn = self.connections.get_thread_connection() |
| 222 | + creds = conn.credentials |
| 223 | + session = boto3.session.Session(region_name=creds.region_name, profile_name=creds.aws_profile_name) |
| 224 | + glue_client = session.client('glue') |
| 225 | + |
| 226 | + logger.debug("CALL glue.delete_table({}, {})", relation.schema, relation.identifier) |
| 227 | + try: |
| 228 | + glue_client.delete_table(DatabaseName=relation.schema, Name=relation.identifier) |
| 229 | + except ClientError as e: |
| 230 | + if e.response['Error']['Code'] == 'EntityNotFoundException': |
| 231 | + logger.debug("Table '{}' does not exists - Ignoring", relation) |
| 232 | + else: |
| 233 | + raise |
0 commit comments