spark-sql-migrations 0.0.6__tar.gz → 0.0.8__tar.gz
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.
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/PKG-INFO +1 -1
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/setup.py +1 -1
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/spark_sql/spark_sql.py +103 -43
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/spark_utils.py +3 -3
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/PKG-INFO +1 -1
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/LICENSE +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/MANIFEST.in +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/backend_shim.py +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/setup.cfg +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/__init__.py +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/migration_templates/default_migration_template.sql +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/migrations_initial/first_01_intial_create_cat.sql +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/migrations_initial/first_02_intial_create_schema.sql +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/migrations_initial/first_03_intial_create_state_table.sql +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/py.typed +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/spark_sql/__init__.py +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/SOURCES.txt +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/dependency_links.txt +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/entry_points.txt +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/namespace_packages.txt +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/requires.txt +0 -0
- {spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/top_level.txt +0 -0
|
@@ -27,8 +27,11 @@ import os
|
|
|
27
27
|
import re
|
|
28
28
|
import uuid
|
|
29
29
|
from dataclasses import dataclass
|
|
30
|
+
from typing import Any, Dict, List, Optional
|
|
30
31
|
|
|
31
32
|
from jinja2 import Environment, FileSystemLoader, PackageLoader, select_autoescape
|
|
33
|
+
from pyspark.sql.session import SparkSession
|
|
34
|
+
from pyspark.sql.types import Row
|
|
32
35
|
|
|
33
36
|
from spark_sql_migrations.spark_utils import get_spark, is_dbr
|
|
34
37
|
|
|
@@ -51,17 +54,17 @@ _COMMENT_OR_BLANK_RE = re.compile(r"^\s*(--.*)?$")
|
|
|
51
54
|
@dataclass(frozen=True)
|
|
52
55
|
class Migration:
|
|
53
56
|
revision_id: str
|
|
54
|
-
prev_revision_id: str
|
|
57
|
+
prev_revision_id: Optional[str]
|
|
55
58
|
template_name: str
|
|
56
59
|
|
|
57
60
|
|
|
58
|
-
def get_default_template_path():
|
|
61
|
+
def get_default_template_path() -> str:
|
|
59
62
|
"""the template this package ships; callers may pass their own instead."""
|
|
60
63
|
return os.path.join(os.path.dirname(__file__), "..", TEMPLATES_PACKAGE_PATH, DEFAULT_TEMPLATE_NAME)
|
|
61
64
|
|
|
62
65
|
|
|
63
|
-
def _parse_migration(migrations_dir, template_name):
|
|
64
|
-
headers = {}
|
|
66
|
+
def _parse_migration(migrations_dir: str, template_name: str) -> Migration:
|
|
67
|
+
headers: Dict[str, Any | str] = {}
|
|
65
68
|
migration_file_path = os.path.join(migrations_dir, template_name)
|
|
66
69
|
if os.path.getsize(migration_file_path) == 0:
|
|
67
70
|
raise ValueError(f"{template_name} is empty;")
|
|
@@ -84,8 +87,8 @@ def _parse_migration(migrations_dir, template_name):
|
|
|
84
87
|
)
|
|
85
88
|
|
|
86
89
|
|
|
87
|
-
def get_ordered_migration_objs(migration_objs):
|
|
88
|
-
by_revision = {}
|
|
90
|
+
def get_ordered_migration_objs(migration_objs: List[Migration]) -> List[Migration]:
|
|
91
|
+
by_revision: Dict[str, Migration] = {}
|
|
89
92
|
for migration in migration_objs:
|
|
90
93
|
clash = by_revision.get(migration.revision_id)
|
|
91
94
|
if clash:
|
|
@@ -102,7 +105,7 @@ def get_ordered_migration_objs(migration_objs):
|
|
|
102
105
|
f"found {[m.template_name for m in roots]};"
|
|
103
106
|
)
|
|
104
107
|
|
|
105
|
-
next_by_revision = {}
|
|
108
|
+
next_by_revision: Dict[str, Migration] = {}
|
|
106
109
|
for migration in migration_objs:
|
|
107
110
|
if not migration.prev_revision_id:
|
|
108
111
|
continue
|
|
@@ -119,7 +122,7 @@ def get_ordered_migration_objs(migration_objs):
|
|
|
119
122
|
next_by_revision[migration.prev_revision_id] = migration
|
|
120
123
|
|
|
121
124
|
ordered = []
|
|
122
|
-
current = roots[0]
|
|
125
|
+
current: Optional[Migration] = roots[0]
|
|
123
126
|
while current:
|
|
124
127
|
ordered.append(current)
|
|
125
128
|
current = next_by_revision.get(current.revision_id)
|
|
@@ -134,8 +137,14 @@ def get_ordered_migration_objs(migration_objs):
|
|
|
134
137
|
return ordered
|
|
135
138
|
|
|
136
139
|
|
|
137
|
-
def get_migrations_list(migrations_dir):
|
|
138
|
-
"""every migration in one directory, walked from its root to its head.
|
|
140
|
+
def get_migrations_list(migrations_dir: str, max_revision_id: Optional[str] = None) -> List[Migration]:
|
|
141
|
+
"""every migration in one directory, walked from its root to its head.
|
|
142
|
+
|
|
143
|
+
``revision_id`` cuts the walk short: the chain is returned up to and including
|
|
144
|
+
the migration carrying that revision. A revision no migration in the directory
|
|
145
|
+
carries is not an error -- the whole chain comes back, same as for no revision
|
|
146
|
+
at all.
|
|
147
|
+
"""
|
|
139
148
|
if not os.path.isdir(migrations_dir):
|
|
140
149
|
raise ValueError(f"no migrations dir at {migrations_dir};")
|
|
141
150
|
|
|
@@ -147,10 +156,18 @@ def get_migrations_list(migrations_dir):
|
|
|
147
156
|
if not migrations:
|
|
148
157
|
return []
|
|
149
158
|
|
|
150
|
-
|
|
159
|
+
ordered = get_ordered_migration_objs(migrations)
|
|
160
|
+
if max_revision_id is None:
|
|
161
|
+
return ordered
|
|
162
|
+
|
|
163
|
+
for index, migration in enumerate(ordered):
|
|
164
|
+
if migration.revision_id == max_revision_id:
|
|
165
|
+
return ordered[: index + 1]
|
|
166
|
+
|
|
167
|
+
return ordered
|
|
151
168
|
|
|
152
169
|
|
|
153
|
-
def get_table_version(spark, cat: str, schema: str):
|
|
170
|
+
def get_table_version(spark: SparkSession, cat: str, schema: str) -> Optional[Row]:
|
|
154
171
|
"""the revision VERSION_TABLE records, or None if it holds no row yet."""
|
|
155
172
|
version_table = f"{cat}.{schema}.{VERSION_TABLE}"
|
|
156
173
|
if not spark.catalog.tableExists(version_table):
|
|
@@ -158,8 +175,10 @@ def get_table_version(spark, cat: str, schema: str):
|
|
|
158
175
|
return spark.read.table(version_table).select("version_num").head()
|
|
159
176
|
|
|
160
177
|
|
|
161
|
-
def get_unapplied_migrations_list(
|
|
162
|
-
|
|
178
|
+
def get_unapplied_migrations_list(
|
|
179
|
+
spark: SparkSession, migrations_dir: str, cat: str, schema: str, max_revision_id: Optional[str] = None
|
|
180
|
+
) -> List[Migration]:
|
|
181
|
+
ordered = get_migrations_list(migrations_dir, max_revision_id)
|
|
163
182
|
current = get_table_version(spark, cat, schema)
|
|
164
183
|
if not current:
|
|
165
184
|
return ordered
|
|
@@ -180,7 +199,7 @@ def get_unapplied_migrations_list(spark, migrations_dir, cat: str, schema: str):
|
|
|
180
199
|
raise ValueError(f"{VERSION_TABLE} is at {current_revision_id}, which matches no migration in {migrations_dir};")
|
|
181
200
|
|
|
182
201
|
|
|
183
|
-
def gate_on_is_dbr(migration_content):
|
|
202
|
+
def gate_on_is_dbr(migration_content: str) -> str:
|
|
184
203
|
"""wrap a migration's body in the jinja conditional, below its headers.
|
|
185
204
|
|
|
186
205
|
the revision headers stay outside it: they are read off the file as comments,
|
|
@@ -199,7 +218,7 @@ def gate_on_is_dbr(migration_content):
|
|
|
199
218
|
|
|
200
219
|
def create_new_migration(
|
|
201
220
|
message: str, template_path: str, output_path: str, truncate_slug_length: int = 40, add_is_dbr: bool = False
|
|
202
|
-
):
|
|
221
|
+
) -> None:
|
|
203
222
|
rev_id = uuid.uuid4().hex[-12:]
|
|
204
223
|
|
|
205
224
|
date_prefix = datetime.datetime.today().strftime("%y%m%d")
|
|
@@ -228,32 +247,38 @@ def create_new_migration(
|
|
|
228
247
|
migration_file.write(default_migration_content)
|
|
229
248
|
|
|
230
249
|
|
|
231
|
-
def apply_template(output_dir, template, cat: str, schema: str):
|
|
250
|
+
def apply_template(output_dir: str, template, cat: str, schema: str) -> str:
|
|
232
251
|
result_sql = template.render(cat=cat, schema=schema, is_dbr=is_dbr())
|
|
233
252
|
with open(os.path.join(output_dir, template.name.replace(".sql", "_primed.sql")), "w") as file_handle:
|
|
234
253
|
file_handle.write(result_sql)
|
|
235
254
|
return result_sql
|
|
236
255
|
|
|
237
256
|
|
|
238
|
-
def get_ascending_letters_within_minute():
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
257
|
+
def get_ascending_letters_within_minute() -> str:
|
|
258
|
+
"""a letter stamp that sorts in the order it was taken, within one minute.
|
|
259
|
+
|
|
260
|
+
the full microseconds since the minute began, not timedelta.microseconds -- that
|
|
261
|
+
holds only the sub-second part and so starts over every second. zero-padded to a
|
|
262
|
+
fixed width, because these are compared as text once they are folder names.
|
|
263
|
+
"""
|
|
264
|
+
now = datetime.datetime.now()
|
|
265
|
+
micros_since_minute = (now - now.replace(second=0, microsecond=0)) // datetime.timedelta(microseconds=1)
|
|
266
|
+
return f"{micros_since_minute:08d}".translate(str.maketrans("0123456789", "ABCDEFGHIJ"))
|
|
242
267
|
|
|
243
268
|
|
|
244
|
-
def get_output_folder(output_parent_path):
|
|
269
|
+
def get_output_folder(output_parent_path: str) -> str:
|
|
245
270
|
folder_name = f"{datetime.datetime.today().strftime('%Y%m%d_%H%M')}_{get_ascending_letters_within_minute()}"
|
|
246
271
|
return os.path.join(output_parent_path, folder_name)
|
|
247
272
|
|
|
248
273
|
|
|
249
|
-
def has_no_statements(rendered_sql):
|
|
274
|
+
def has_no_statements(rendered_sql: str) -> bool:
|
|
250
275
|
for line in rendered_sql.splitlines():
|
|
251
276
|
if not _COMMENT_OR_BLANK_RE.match(line):
|
|
252
277
|
return False
|
|
253
278
|
return True
|
|
254
279
|
|
|
255
280
|
|
|
256
|
-
def render_and_apply(spark, output_folder, template, cat: str, schema: str):
|
|
281
|
+
def render_and_apply(spark: SparkSession, output_folder: str, template, cat: str, schema: str) -> None:
|
|
257
282
|
"""render one migration and run it, unless this engine was gated out of it."""
|
|
258
283
|
result_sql = apply_template(output_folder, template, cat=cat, schema=schema)
|
|
259
284
|
if has_no_statements(result_sql):
|
|
@@ -262,7 +287,7 @@ def render_and_apply(spark, output_folder, template, cat: str, schema: str):
|
|
|
262
287
|
spark.sql(result_sql)
|
|
263
288
|
|
|
264
289
|
|
|
265
|
-
def migrate_initial(spark, output_folder, cat: str, schema: str):
|
|
290
|
+
def migrate_initial(spark: SparkSession, output_folder: str, cat: str, schema: str) -> None:
|
|
266
291
|
"""apply the package's own bootstrap chain, in filename order rather than by revision."""
|
|
267
292
|
env = Environment(
|
|
268
293
|
loader=PackageLoader(package_name=PACKAGE_NAME, package_path=INITIAL_MIGRATIONS_PACKAGE_PATH),
|
|
@@ -276,14 +301,21 @@ def migrate_initial(spark, output_folder, cat: str, schema: str):
|
|
|
276
301
|
logger.info(f"rendered {len(all_templates)} initial migrations;")
|
|
277
302
|
|
|
278
303
|
|
|
279
|
-
def record_revision(spark, cat: str, schema: str, revision_id: str):
|
|
304
|
+
def record_revision(spark: SparkSession, cat: str, schema: str, revision_id: str) -> None:
|
|
280
305
|
version_table = f"{cat}.{schema}.{VERSION_TABLE}"
|
|
281
306
|
revision_literal = revision_id.replace("'", "''")
|
|
282
307
|
spark.sql(f"delete from {version_table}")
|
|
283
308
|
spark.sql(f"insert into {version_table} (version_num) values ('{revision_literal}')")
|
|
284
309
|
|
|
285
310
|
|
|
286
|
-
def
|
|
311
|
+
def upgrade(
|
|
312
|
+
spark: SparkSession,
|
|
313
|
+
output_folder: str,
|
|
314
|
+
migrations_dir: str,
|
|
315
|
+
cat: str,
|
|
316
|
+
schema: str,
|
|
317
|
+
max_revision_id: Optional[str] = None,
|
|
318
|
+
) -> None:
|
|
287
319
|
"""
|
|
288
320
|
TODO XXX permit applying up to a revision below the head revision
|
|
289
321
|
TODO XXX add backwards migrations, permit migrating backwards
|
|
@@ -291,7 +323,9 @@ def migrate_w_rev(spark, output_folder, migrations_dir, cat: str, schema: str):
|
|
|
291
323
|
if not os.path.isdir(migrations_dir):
|
|
292
324
|
logger.info(f"no chain at {migrations_dir}; skipping it;")
|
|
293
325
|
return
|
|
294
|
-
unapplied = get_unapplied_migrations_list(
|
|
326
|
+
unapplied = get_unapplied_migrations_list(
|
|
327
|
+
spark, migrations_dir, cat=cat, schema=schema, max_revision_id=max_revision_id
|
|
328
|
+
)
|
|
295
329
|
|
|
296
330
|
logger.info(
|
|
297
331
|
f"{len(unapplied)} unapplied migrations; "
|
|
@@ -305,7 +339,14 @@ def migrate_w_rev(spark, output_folder, migrations_dir, cat: str, schema: str):
|
|
|
305
339
|
logger.info(f"{migration.template_name} done; now at {migration.revision_id};")
|
|
306
340
|
|
|
307
341
|
|
|
308
|
-
def
|
|
342
|
+
def run_upgrade(
|
|
343
|
+
spark: SparkSession,
|
|
344
|
+
cat: str,
|
|
345
|
+
schema: str,
|
|
346
|
+
output_folder: str,
|
|
347
|
+
migrations_dir: str,
|
|
348
|
+
max_revision_id: Optional[str] = None,
|
|
349
|
+
) -> None:
|
|
309
350
|
initial_output_folder = os.path.join(output_folder, INITIAL_MIGRATIONS_PACKAGE_PATH)
|
|
310
351
|
client_output_folder = os.path.join(output_folder, CLIENT_OUTPUT_DIRNAME)
|
|
311
352
|
os.makedirs(initial_output_folder, exist_ok=True)
|
|
@@ -315,42 +356,61 @@ def run_migrations(spark, cat, schema, output_folder, migrations_dir):
|
|
|
315
356
|
logger.info(f"{version_table} already exists; skipping the initial migrations;")
|
|
316
357
|
else:
|
|
317
358
|
migrate_initial(spark, initial_output_folder, cat, schema)
|
|
318
|
-
|
|
359
|
+
upgrade(spark, client_output_folder, migrations_dir, cat, schema, max_revision_id)
|
|
319
360
|
|
|
320
361
|
|
|
321
|
-
def main(
|
|
362
|
+
def main(
|
|
363
|
+
cat: str,
|
|
364
|
+
schema: str,
|
|
365
|
+
migrations_dir: str,
|
|
366
|
+
output_parent_path: Optional[str] = None,
|
|
367
|
+
max_revision_id: Optional[str] = None,
|
|
368
|
+
) -> None:
|
|
322
369
|
output_folder = get_output_folder(output_parent_path or os.path.join(os.getcwd(), "migrations_out"))
|
|
323
370
|
os.makedirs(output_folder)
|
|
324
|
-
|
|
371
|
+
run_upgrade(get_spark(), cat, schema, output_folder, migrations_dir, max_revision_id)
|
|
325
372
|
|
|
326
373
|
|
|
327
|
-
def _cli_main(
|
|
328
|
-
|
|
374
|
+
def _cli_main(
|
|
375
|
+
cat: str, schema: str, migrations_dir: str, max_revision_id: Optional[str] = None
|
|
376
|
+
) -> None: # pragma: no cover
|
|
377
|
+
main(cat, schema, migrations_dir, max_revision_id=max_revision_id)
|
|
329
378
|
|
|
330
379
|
|
|
331
|
-
def _cli_create_new_migration(
|
|
380
|
+
def _cli_create_new_migration(
|
|
381
|
+
message: str, output_path: str, template_path: str, add_is_dbr: bool
|
|
382
|
+
) -> None: # pragma: no cover
|
|
332
383
|
create_new_migration(message, template_path or get_default_template_path(), output_path, add_is_dbr=add_is_dbr)
|
|
333
384
|
|
|
334
385
|
|
|
335
|
-
def build_parser(): # pragma: no cover
|
|
386
|
+
def build_parser() -> argparse.ArgumentParser: # pragma: no cover
|
|
336
387
|
parser = argparse.ArgumentParser(description="spark_sql_migrations migration utilities")
|
|
337
388
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
338
389
|
|
|
339
|
-
p_run = subparsers.add_parser("run", help="apply
|
|
340
|
-
p_run.add_argument("--cat", default="spark_catalog")
|
|
341
|
-
p_run.add_argument("--schema", default="default")
|
|
342
|
-
p_run.add_argument("--migrations-dir", required=True, help="the directory holding the migration chain")
|
|
390
|
+
p_run = subparsers.add_parser("run", help="upgrade to head/apply pending migrations")
|
|
391
|
+
p_run.add_argument("--cat", type=str, default="spark_catalog")
|
|
392
|
+
p_run.add_argument("--schema", type=str, default="default")
|
|
393
|
+
p_run.add_argument("--migrations-dir", type=str, required=True, help="the directory holding the migration chain")
|
|
394
|
+
p_run.add_argument(
|
|
395
|
+
"--max-revision-id",
|
|
396
|
+
type=str,
|
|
397
|
+
default=None,
|
|
398
|
+
help="apply the migration carrying this revision_id and stop; defaults to applying the chain to its head",
|
|
399
|
+
)
|
|
343
400
|
p_run.set_defaults(func=_cli_main)
|
|
344
401
|
|
|
345
402
|
p_create = subparsers.add_parser("create_new_migration", help="create a new migration from the template")
|
|
346
|
-
p_create.add_argument("--message", required=True)
|
|
403
|
+
p_create.add_argument("--message", type=str, required=True)
|
|
347
404
|
p_create.add_argument(
|
|
348
405
|
"--output-path",
|
|
406
|
+
type=str,
|
|
349
407
|
required=True,
|
|
350
408
|
help="the chain directory to write the new migration into. if sql files are in there, the last sql's rev_id"
|
|
351
409
|
"will be set as the new migrations prev_rev_id.",
|
|
352
410
|
)
|
|
353
|
-
p_create.add_argument(
|
|
411
|
+
p_create.add_argument(
|
|
412
|
+
"--template-path", type=str, default=None, help="defaults to the template shipped in this package"
|
|
413
|
+
)
|
|
354
414
|
# the %% are argparse's: it interpolates help strings
|
|
355
415
|
p_create.add_argument(
|
|
356
416
|
"--add-is-dbr",
|
|
@@ -362,7 +422,7 @@ def build_parser(): # pragma: no cover
|
|
|
362
422
|
return parser
|
|
363
423
|
|
|
364
424
|
|
|
365
|
-
def cli(argv=None): # pragma: no cover
|
|
425
|
+
def cli(argv: Optional[list[str]] = None) -> None: # pragma: no cover
|
|
366
426
|
"""the `spark-sql-migrations` console command.
|
|
367
427
|
|
|
368
428
|
an application entry point, so unlike the rest of this package it configures
|
{spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/spark_utils.py
RENAMED
|
@@ -11,7 +11,7 @@ METASTORE_DIR_ENV_VAR = "SPARK_METASTORE_DIR"
|
|
|
11
11
|
DEFAULT_WAREHOUSE_DIRNAME = "spark-warehouse"
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def is_dbr():
|
|
14
|
+
def is_dbr() -> bool:
|
|
15
15
|
try:
|
|
16
16
|
from pyspark.dbutils import DBUtils # type: ignore # noqa: F401
|
|
17
17
|
|
|
@@ -21,7 +21,7 @@ def is_dbr():
|
|
|
21
21
|
return False
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def get_warehouse_dir():
|
|
24
|
+
def get_warehouse_dir() -> str:
|
|
25
25
|
"""where local (non-DBR) spark keeps its warehouse.
|
|
26
26
|
|
|
27
27
|
resolved against the caller's cwd, never against __file__: installed from a
|
|
@@ -34,7 +34,7 @@ def get_warehouse_dir():
|
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def get_spark(use_dbc=False):
|
|
37
|
+
def get_spark(use_dbc: bool = False) -> SparkSession:
|
|
38
38
|
if use_dbc or is_dbr():
|
|
39
39
|
from databricks.connect.session import DatabricksSession # type: ignore # pants: no-infer-dep
|
|
40
40
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations/spark_sql/__init__.py
RENAMED
|
File without changes
|
{spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{spark_sql_migrations-0.0.6 → spark_sql_migrations-0.0.8}/spark_sql_migrations.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|