dbt-firebolt 1.9.4__py3-none-any.whl → 1.10.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ from dbt.adapters.firebolt.connections import (
7
7
  from dbt.adapters.firebolt.impl import FireboltAdapter
8
8
  from dbt.include import firebolt
9
9
 
10
- __version__ = "1.9.4"
10
+ __version__ = "1.10.0"
11
11
 
12
12
  Plugin = AdapterPlugin(
13
13
  adapter=FireboltAdapter, # type: ignore
@@ -19,7 +19,12 @@ from dbt_common.exceptions import (
19
19
  NotImplementedError,
20
20
  )
21
21
  from firebolt.client import DEFAULT_API_URL
22
- from firebolt.client.auth import Auth, ClientCredentials, UsernamePassword
22
+ from firebolt.client.auth import (
23
+ Auth,
24
+ ClientCredentials,
25
+ FireboltCore,
26
+ UsernamePassword,
27
+ )
23
28
  from firebolt.db import ARRAY, DECIMAL, ExtendedType
24
29
  from firebolt.db import connect as sdk_connect
25
30
  from firebolt.db.connection import Connection as SDKConnection
@@ -41,6 +46,7 @@ class FireboltCredentials(Credentials):
41
46
  api_endpoint: Optional[str] = DEFAULT_API_URL
42
47
  engine_name: Optional[str] = None
43
48
  account_name: Optional[str] = None
49
+ url: Optional[str] = None
44
50
  retries: int = 1
45
51
 
46
52
  _ALIASES = {
@@ -48,26 +54,14 @@ class FireboltCredentials(Credentials):
48
54
  }
49
55
 
50
56
  def __post_init__(self) -> None:
51
- # If user and password are not provided, assume client_id and client_secret
52
- # are provided instead
53
- if not self.user and not self.password:
54
- if not self.client_id or not self.client_secret:
55
- raise DbtConfigError(
56
- 'Either user and password or client_id and client_secret'
57
- ' must be provided'
58
- )
59
- else:
60
- if self.client_id or self.client_secret:
61
- raise DbtConfigError(
62
- 'Either user and password or client_id and client_secret'
63
- ' must be provided'
64
- )
57
+ # Check the credentials are valid and we can determine the auth method
58
+ _determine_auth(self)
65
59
 
66
60
  @property
67
61
  def type(self) -> str:
68
62
  return 'firebolt'
69
63
 
70
- def _connection_keys(self) -> Tuple[str, str, str, str, str, str, str]:
64
+ def _connection_keys(self) -> Tuple[str, str, str, str, str, str, str, str]:
71
65
  """
72
66
  Return tuple of keys (i.e. not values) to display
73
67
  in the `dbt debug` output.
@@ -80,6 +74,7 @@ class FireboltCredentials(Credentials):
80
74
  'database',
81
75
  'engine_name',
82
76
  'params',
77
+ 'url',
83
78
  )
84
79
 
85
80
  @property
@@ -222,17 +217,50 @@ class FireboltConnectionManager(SQLConnectionManager):
222
217
 
223
218
 
224
219
  def _determine_auth(credentials: FireboltCredentials) -> Auth:
225
- if credentials.client_id and credentials.client_secret:
226
- return ClientCredentials(credentials.client_id, credentials.client_secret)
227
- elif '@' in credentials.user: # type: ignore # checked in the dataclass
228
- # email auth can only be used with UsernamePassword
229
- return UsernamePassword(
230
- credentials.user, # type: ignore[arg-type]
231
- credentials.password, # type: ignore[arg-type]
232
- )
233
- else:
234
- # assume user provided id and secret in the user/password fields
220
+ """Determine the appropriate authentication method based on provided credentials."""
221
+
222
+ def _has_client_credentials() -> bool:
223
+ return bool(credentials.client_id and credentials.client_secret)
224
+
225
+ def _has_user_password() -> bool:
226
+ return bool(credentials.user and credentials.password)
227
+
228
+ def _is_email_auth() -> bool:
229
+ return bool(credentials.user and '@' in credentials.user)
230
+
231
+ # Handle Firebolt Core authentication (no other credentials allowed)
232
+ if credentials.url:
233
+ if _has_client_credentials() or _has_user_password():
234
+ raise DbtConfigError(
235
+ 'If url is provided, do not provide user, password, '
236
+ 'client_id, or client_secret.'
237
+ )
238
+ return FireboltCore()
239
+
240
+ # Handle client credentials authentication
241
+ if _has_client_credentials():
235
242
  return ClientCredentials(
236
- credentials.user, # type: ignore[arg-type]
237
- credentials.password, # type: ignore[arg-type]
243
+ credentials.client_id, # type: ignore[arg-type]
244
+ credentials.client_secret, # type: ignore[arg-type]
238
245
  )
246
+
247
+ # Handle username/password authentication
248
+ if _has_user_password():
249
+ if _is_email_auth():
250
+ return UsernamePassword(
251
+ credentials.user, # type: ignore[arg-type]
252
+ credentials.password, # type: ignore[arg-type]
253
+ )
254
+ else:
255
+ return ClientCredentials(
256
+ credentials.user, # type: ignore[arg-type]
257
+ credentials.password, # type: ignore[arg-type]
258
+ )
259
+
260
+ # If we reach here, no valid authentication method was found
261
+ raise DbtConfigError(
262
+ 'No valid authentication method found. Provide either:\n'
263
+ '- client_id and client_secret\n'
264
+ '- user and password\n'
265
+ '- or use url for Firebolt Core connection'
266
+ )
@@ -313,7 +313,8 @@ class FireboltAdapter(SQLAdapter):
313
313
  names = sorted((self.quote(n) for n in column_names))
314
314
 
315
315
  where_expressions = [
316
- f'{relation_a}.{name} = {relation_b}.{name}' for name in names
316
+ f'{relation_a}.{name} IS NOT DISTINCT FROM {relation_b}.{name}'
317
+ for name in names
317
318
  ]
318
319
  where_clause = ' AND '.join(where_expressions)
319
320
  columns_csv = ', '.join(names)
@@ -7,9 +7,15 @@
7
7
  {% macro firebolt__create_csv_table(model, agate_table) %}
8
8
  {%- set column_override = model['config'].get('column_types', {}) -%}
9
9
  {%- set quote_seed_column = model['config'].get('quote_columns', None) -%}
10
+ {%- set is_firebolt_core = target.url is defined and target.url -%}
11
+ {%- set default_table_type = 'fact' if is_firebolt_core else 'dimension' -%}
12
+ {%- set table_type = config.get(
13
+ 'table_type',
14
+ default = default_table_type
15
+ ) | upper -%}
10
16
  {% set sql %}
11
17
 
12
- CREATE DIMENSION TABLE IF NOT EXISTS {{ this.render() }} (
18
+ CREATE {{ table_type }} TABLE IF NOT EXISTS {{ this.render() }} (
13
19
  {%- for col_name in agate_table.column_names -%}
14
20
  {%- set inferred_type = adapter.convert_type(agate_table, loop.index0) -%}
15
21
  {%- set type = column_override.get(col_name, inferred_type) -%}
@@ -28,9 +28,11 @@
28
28
  {%- do adapter.drop_relation(relation) -%}
29
29
  {%- endif -%}
30
30
 
31
+ {%- set is_firebolt_core = target.url is defined and target.url -%}
32
+ {%- set default_table_type = 'fact' if is_firebolt_core else 'dimension' -%}
31
33
  {%- set table_type = config.get(
32
34
  'table_type',
33
- default = 'dimension'
35
+ default = default_table_type
34
36
  ) | upper -%}
35
37
  {%- set primary_index = config.get('primary_index') -%}
36
38
  {%- set incremental_strategy = config.get('incremental_strategy') -%}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbt_firebolt
3
- Version: 1.9.4
3
+ Version: 1.10.0
4
4
  Summary: The Firebolt adapter plugin for dbt (data build tool)
5
5
  Home-page: https://github.com/firebolt-db/dbt-firebolt
6
6
  Author: Firebolt
@@ -21,7 +21,7 @@ Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  Requires-Dist: dbt-adapters <2.0,>=1.0
23
23
  Requires-Dist: dbt-core >=1.8.0
24
- Requires-Dist: firebolt-sdk >=1.8.1
24
+ Requires-Dist: firebolt-sdk >=1.13.0
25
25
  Requires-Dist: pydantic >=0.23
26
26
  Provides-Extra: dev
27
27
  Requires-Dist: allure-pytest ==2.* ; extra == 'dev'
@@ -1,8 +1,8 @@
1
- dbt/adapters/firebolt/__init__.py,sha256=2mzeaeqKIIFSrISgifexUgK6B1CAd-F3yGKujM-hHbE,411
1
+ dbt/adapters/firebolt/__init__.py,sha256=Btjr0YIH7k2MvVw5aWEddUq5zIZpSQF_YSzNGKhXuXY,412
2
2
  dbt/adapters/firebolt/__version__.py,sha256=zRlZGglif76ZVuWWSjsH_MMPgtVQqmj-SryYJW25FL4,69
3
3
  dbt/adapters/firebolt/column.py,sha256=COo_wjhCFgS3GFcPIPcoq7WAWgzN6DB2XqG-gk51WBc,539
4
- dbt/adapters/firebolt/connections.py,sha256=dNdha5dDEYUPhLvlSq8_ftbBA1hiqnUCBukt6wLuZH4,7976
5
- dbt/adapters/firebolt/impl.py,sha256=eIqnXzoMoyHq2lp1yMz7O62WJ0apM16H8IssTTwDMiw,15075
4
+ dbt/adapters/firebolt/connections.py,sha256=W2dwwtuQAUTbpmV2gKhYhcmq9j6xB0BwyWmypSQBY7s,8629
5
+ dbt/adapters/firebolt/impl.py,sha256=zH7X-vHDCbv_c7yHt_nS6JMN850THaE3rABqCRn76I4,15106
6
6
  dbt/adapters/firebolt/relation.py,sha256=Xg3Nrjw3UrF_qwnuGbPT97rSXRiDP1GlIAoBF4b7QnY,1922
7
7
  dbt/adapters/firebolt/relation_configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  dbt/include/firebolt/__init__.py,sha256=vBGWeG-dHHkimfnX8axBJ4IgAowFw8xADmo6Auzn2xc,52
@@ -16,7 +16,7 @@ dbt/include/firebolt/macros/dbt_external_tables/dropif.sql,sha256=-kZzUVgC6Bcof7
16
16
  dbt/include/firebolt/macros/dbt_external_tables/get_external_build_plan.sql,sha256=BWNSuqB9t0hxbxL9CbIc0UFTBBarQMtGfHv9LLAbqSI,894
17
17
  dbt/include/firebolt/macros/materializations/clone.sql,sha256=SKPc_tG0tF2HRKlo1-CQPvxVWGKHpXDwxvubsCwKTG8,79
18
18
  dbt/include/firebolt/macros/materializations/materialized_view.sql,sha256=pdWGMP25o0RqNINx1hbn1Q4dTNcdk0Dgrlv3K8XQAbs,202
19
- dbt/include/firebolt/macros/materializations/seed.sql,sha256=O622lwmzRGeAfaNfRpjR183ARFltILteznwgXZfPXMA,1564
19
+ dbt/include/firebolt/macros/materializations/seed.sql,sha256=QXL5AugRq6sRv1XP-QOgInjvSkXErfxvsGoQXn1ULXk,1830
20
20
  dbt/include/firebolt/macros/materializations/snapshot_merge.sql,sha256=9Y4tGWkqkBDt53QHKxJPFALboKQxDJ4ZaSrLwNyRgIs,795
21
21
  dbt/include/firebolt/macros/materializations/table.sql,sha256=XY0D-df9EoWOBF3kCT3TCE3Rko7bvvfuztQT0-Pqlfs,1752
22
22
  dbt/include/firebolt/macros/materializations/test.sql,sha256=Wol19pNIfkPRTpVUYKAGbkipYOMZjixnAaoZ1chuP88,488
@@ -32,7 +32,7 @@ dbt/include/firebolt/macros/relations/materialized_view/create.sql,sha256=xthF0o
32
32
  dbt/include/firebolt/macros/relations/materialized_view/describe.sql,sha256=uMJWY-9P-49YjhwH_F1Co4szia0oNAVYqJIv2IVGzM8,164
33
33
  dbt/include/firebolt/macros/relations/materialized_view/drop.sql,sha256=Ya03cid5h05t3-SIF4JndKtMMIctD46OX9gPVt9jhVw,160
34
34
  dbt/include/firebolt/macros/relations/materialized_view/refresh.sql,sha256=9s4e6cjT9Dx9nCCJPMlhV5SkzHX8574cdIJUhSfNmU8,163
35
- dbt/include/firebolt/macros/relations/table/create.sql,sha256=5FK3XOICE-9LGojHzh0pjCy5wO-RKyeytzkEQmYT7zY,2507
35
+ dbt/include/firebolt/macros/relations/table/create.sql,sha256=guTzPeg1RHf3OksEXDPBNKjhQngtwF5fxv9Yhvq6Bag,2667
36
36
  dbt/include/firebolt/macros/relations/table/drop.sql,sha256=3W0SMqmlDizmZqn-QZvqXeJ9lG2KtooiFvwac3WzSzQ,110
37
37
  dbt/include/firebolt/macros/relations/table/rename.sql,sha256=5dmKvuiSnMTARuthnDJBUOORdQCIeEuGMLoyZlgQxVU,185
38
38
  dbt/include/firebolt/macros/relations/table/replace.sql,sha256=bw08YDtLMhkM4dO4nYXZ32U50lcnTG5Axb-Lls7XpB0,132
@@ -54,8 +54,8 @@ dbt/include/firebolt/macros/utils/position.sql,sha256=WPo9_bhvNYJooEAsHC9OcnNAwU
54
54
  dbt/include/firebolt/macros/utils/right.sql,sha256=_mm1_2MvlOH4O6CmYhgvVxMLfDxAvgv-EMwZ8OBOq-I,254
55
55
  dbt/include/firebolt/macros/utils/split_part.sql,sha256=5dUlbx3Pt1iWWaIlxiXyYUwUqzXuLLXMB-1aGJHNk4o,464
56
56
  dbt/include/firebolt/macros/utils/timestamps.sql,sha256=22g-QpJjBuBUQOHNpQ_TuMRa-cHxaxXPv8ItEUo-vEk,397
57
- dbt_firebolt-1.9.4.dist-info/LICENSE,sha256=Nn0EGvW3qmoZpBV_JVM3iPukFf3RiNCIizrWe_2oTHk,11354
58
- dbt_firebolt-1.9.4.dist-info/METADATA,sha256=3-AADXMb9idiZhJ0qG0jvHJU33WkHs3EgPB9Y2UygH0,5237
59
- dbt_firebolt-1.9.4.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
60
- dbt_firebolt-1.9.4.dist-info/top_level.txt,sha256=B2YH4he17ajilEWOGCKHbRcEJlCuZKwCcgFcLPntLsE,4
61
- dbt_firebolt-1.9.4.dist-info/RECORD,,
57
+ dbt_firebolt-1.10.0.dist-info/LICENSE,sha256=Nn0EGvW3qmoZpBV_JVM3iPukFf3RiNCIizrWe_2oTHk,11354
58
+ dbt_firebolt-1.10.0.dist-info/METADATA,sha256=qnmcCtmjTKojTv1wQ4rncu4zoGYILlsEMhhY1xIR5Ck,5239
59
+ dbt_firebolt-1.10.0.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
60
+ dbt_firebolt-1.10.0.dist-info/top_level.txt,sha256=B2YH4he17ajilEWOGCKHbRcEJlCuZKwCcgFcLPntLsE,4
61
+ dbt_firebolt-1.10.0.dist-info/RECORD,,