13
13
from sqeleton .schema import create_schema
14
14
from sqeleton .queries .api import current_timestamp
15
15
16
+ from .dbt import dbt_diff
16
17
from .utils import eval_name_template , remove_password_from_url , safezip , match_like
17
18
from .diff_tables import Algorithm
18
19
from .hashdiff_tables import HashDiffer , DEFAULT_BISECTION_THRESHOLD , DEFAULT_BISECTION_FACTOR
@@ -185,7 +186,11 @@ def write_usage(self, prog: str, args: str = "", prefix: Optional[str] = None) -
185
186
metavar = "COUNT" ,
186
187
)
187
188
@click .option (
188
- "-w" , "--where" , default = None , help = "An additional 'where' expression to restrict the search space. Beware of SQL Injection!" , metavar = "EXPR"
189
+ "-w" ,
190
+ "--where" ,
191
+ default = None ,
192
+ help = "An additional 'where' expression to restrict the search space. Beware of SQL Injection!" ,
193
+ metavar = "EXPR" ,
189
194
)
190
195
@click .option ("-a" , "--algorithm" , default = Algorithm .AUTO .value , type = click .Choice ([i .value for i in Algorithm ]))
191
196
@click .option (
@@ -200,24 +205,74 @@ def write_usage(self, prog: str, args: str = "", prefix: Optional[str] = None) -
200
205
help = "Name of run-configuration to run. If used, CLI arguments for database and table must be omitted." ,
201
206
metavar = "NAME" ,
202
207
)
208
+ @click .option (
209
+ "--dbt" ,
210
+ is_flag = True ,
211
+ help = "Run a diff using your local dbt project. Expects to be run from a dbt project folder by default." ,
212
+ )
213
+ @click .option (
214
+ "--cloud" ,
215
+ is_flag = True ,
216
+ help = "Add this flag along with --dbt to run a diff using your local dbt project on Datafold cloud. Expects an api key on env var DATAFOLD_API_KEY." ,
217
+ )
218
+ @click .option (
219
+ "--dbt-profiles-dir" ,
220
+ default = None ,
221
+ metavar = "PATH" ,
222
+ help = "Override the default dbt profile location (~/.dbt)." ,
223
+ )
224
+ @click .option (
225
+ "--dbt-project-dir" ,
226
+ default = None ,
227
+ metavar = "PATH" ,
228
+ help = "Override the dbt project directory. Otherwise assumed to be the current directory." ,
229
+ )
203
230
def main (conf , run , ** kw ):
204
231
if kw ["table2" ] is None and kw ["database2" ]:
205
232
# Use the "database table table" form
206
233
kw ["table2" ] = kw ["database2" ]
207
234
kw ["database2" ] = kw ["database1" ]
208
235
236
+ if kw ["version" ]:
237
+ print (f"v{ __version__ } " )
238
+ return
239
+
209
240
if conf :
210
241
kw = apply_config_from_file (conf , run , kw )
211
242
243
+ if kw ["no_tracking" ]:
244
+ disable_tracking ()
245
+
246
+ if kw .get ("interactive" ):
247
+ kw ["debug" ] = True
248
+
249
+ if kw ["debug" ]:
250
+ logging .basicConfig (level = logging .DEBUG , format = LOG_FORMAT , datefmt = DATE_FORMAT )
251
+ if kw .get ("__conf__" ):
252
+ kw ["__conf__" ] = deepcopy (kw ["__conf__" ])
253
+ _remove_passwords_in_dict (kw ["__conf__" ])
254
+ logging .debug (f"Applied run configuration: { kw ['__conf__' ]} " )
255
+ elif kw .get ("verbose" ):
256
+ logging .basicConfig (level = logging .INFO , format = LOG_FORMAT , datefmt = DATE_FORMAT )
257
+ else :
258
+ logging .basicConfig (level = logging .WARNING , format = LOG_FORMAT , datefmt = DATE_FORMAT )
259
+
212
260
try :
213
- return _main (** kw )
261
+ if kw ["dbt" ]:
262
+ dbt_diff (
263
+ profiles_dir_override = kw ["dbt_profiles_dir" ],
264
+ project_dir_override = kw ["dbt_project_dir" ],
265
+ is_cloud = kw ["cloud" ],
266
+ )
267
+ else :
268
+ return _data_diff (** kw )
214
269
except Exception as e :
215
270
logging .error (e )
216
271
if kw ["debug" ]:
217
272
raise
218
273
219
274
220
- def _main (
275
+ def _data_diff (
221
276
database1 ,
222
277
table1 ,
223
278
database2 ,
@@ -246,31 +301,14 @@ def _main(
246
301
materialize_all_rows ,
247
302
table_write_limit ,
248
303
materialize_to_table ,
304
+ dbt ,
305
+ cloud ,
306
+ dbt_profiles_dir ,
307
+ dbt_project_dir ,
249
308
threads1 = None ,
250
309
threads2 = None ,
251
310
__conf__ = None ,
252
311
):
253
- if version :
254
- print (f"v{ __version__ } " )
255
- return
256
-
257
- if no_tracking :
258
- disable_tracking ()
259
-
260
- if interactive :
261
- debug = True
262
-
263
- if debug :
264
- logging .basicConfig (level = logging .DEBUG , format = LOG_FORMAT , datefmt = DATE_FORMAT )
265
- if __conf__ :
266
- __conf__ = deepcopy (__conf__ )
267
- _remove_passwords_in_dict (__conf__ )
268
- logging .debug (f"Applied run configuration: { __conf__ } " )
269
- elif verbose :
270
- logging .basicConfig (level = logging .INFO , format = LOG_FORMAT , datefmt = DATE_FORMAT )
271
- else :
272
- logging .basicConfig (level = logging .WARNING , format = LOG_FORMAT , datefmt = DATE_FORMAT )
273
-
274
312
if limit and stats :
275
313
logging .error ("Cannot specify a limit when using the -s/--stats switch" )
276
314
return
0 commit comments