spark-sql-migrations 0.0.3__tar.gz → 0.0.5__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.3 → spark_sql_migrations-0.0.5}/PKG-INFO +6 -4
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/setup.py +6 -4
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/spark_sql/spark_sql.py +28 -14
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/PKG-INFO +6 -4
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/LICENSE +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/MANIFEST.in +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/backend_shim.py +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/setup.cfg +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/__init__.py +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/migration_templates/default_migration_template.sql +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/migrations_initial/first_01_intial_create_cat_dbr_only.sql +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/migrations_initial/first_02_intial_create_schema_all.sql +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/migrations_initial/first_03_intial_create_state_table_all.sql +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/py.typed +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/spark_sql/__init__.py +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/spark_utils.py +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/SOURCES.txt +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/dependency_links.txt +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/entry_points.txt +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/namespace_packages.txt +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/requires.txt +0 -0
- {spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spark_sql_migrations
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5
|
|
4
4
|
Summary: Chained, idempotent SQL migrations for Spark and Databricks.
|
|
5
5
|
Home-page: https://github.com/mcjug2015/spark_sql_migrations
|
|
6
6
|
Author: Victor Semenov
|
|
@@ -81,10 +81,12 @@ Migrations come from two different owners, and they behave differently:
|
|
|
81
81
|
| **what** | catalog, schema, `_spark_migrations_version` table | your tables and columns |
|
|
82
82
|
| **where** | `spark_sql_migrations/migrations_initial/` | `all_spark_migrations/`, `dbr_only_migrations/` |
|
|
83
83
|
| **selected by** | filename suffix — `_all.sql` everywhere, `_dbr_only.sql` on Databricks | the `prev_revision_id` chain |
|
|
84
|
-
| **when applied** |
|
|
84
|
+
| **when applied** | until the version table exists | once, then recorded |
|
|
85
85
|
|
|
86
|
-
The bootstrap chain is
|
|
87
|
-
|
|
86
|
+
The bootstrap chain is applied on every run until `_spark_migrations_version` exists, and
|
|
87
|
+
skipped from then on. A run that fails partway through bootstrapping replays it, so it must
|
|
88
|
+
still be idempotent. Your own chains are applied once each and their head revision is
|
|
89
|
+
written to the version table.
|
|
88
90
|
|
|
89
91
|
## Laying out your chains
|
|
90
92
|
|
|
@@ -82,10 +82,12 @@ Migrations come from two different owners, and they behave differently:
|
|
|
82
82
|
| **what** | catalog, schema, `_spark_migrations_version` table | your tables and columns |
|
|
83
83
|
| **where** | `spark_sql_migrations/migrations_initial/` | `all_spark_migrations/`, `dbr_only_migrations/` |
|
|
84
84
|
| **selected by** | filename suffix — `_all.sql` everywhere, `_dbr_only.sql` on Databricks | the `prev_revision_id` chain |
|
|
85
|
-
| **when applied** |
|
|
85
|
+
| **when applied** | until the version table exists | once, then recorded |
|
|
86
86
|
|
|
87
|
-
The bootstrap chain is
|
|
88
|
-
|
|
87
|
+
The bootstrap chain is applied on every run until `_spark_migrations_version` exists, and
|
|
88
|
+
skipped from then on. A run that fails partway through bootstrapping replays it, so it must
|
|
89
|
+
still be idempotent. Your own chains are applied once each and their head revision is
|
|
90
|
+
written to the version table.
|
|
89
91
|
|
|
90
92
|
## Laying out your chains
|
|
91
93
|
|
|
@@ -252,5 +254,5 @@ Apache License 2.0 — see [LICENSE](LICENSE).
|
|
|
252
254
|
},
|
|
253
255
|
'python_requires': '>=3.10',
|
|
254
256
|
'url': 'https://github.com/mcjug2015/spark_sql_migrations',
|
|
255
|
-
'version': '0.0.
|
|
257
|
+
'version': '0.0.5',
|
|
256
258
|
})
|
|
@@ -5,7 +5,8 @@ Two kinds of migration exist, and they are owned by different parties:
|
|
|
5
5
|
* the *initial* chain and the new-migration template ship inside this package.
|
|
6
6
|
They bootstrap the catalog, the schema and the version table, are selected by
|
|
7
7
|
filename suffix (``_all.sql`` / ``_dbr_only.sql``) rather than by revision,
|
|
8
|
-
and are
|
|
8
|
+
and are applied on every run until the version table exists -- so a run that
|
|
9
|
+
failed partway through replays them, and they must be idempotent.
|
|
9
10
|
* the ``all_spark_migrations/`` and ``dbr_only_migrations/`` chains belong to
|
|
10
11
|
the consuming project. The caller passes their parent directory as
|
|
11
12
|
``migrations_root``; each chain is walked from its root via
|
|
@@ -149,20 +150,20 @@ def get_migrations_list(migrations_dir):
|
|
|
149
150
|
return get_ordered_migration_objs(migrations)
|
|
150
151
|
|
|
151
152
|
|
|
153
|
+
def get_table_version(spark, migration_type, cat: str, schema: str):
|
|
154
|
+
version_table = f"{cat}.{schema}.{VERSION_TABLE}"
|
|
155
|
+
if not spark.catalog.tableExists(version_table):
|
|
156
|
+
return None
|
|
157
|
+
return spark.read.table(version_table).where(col("migration_type") == migration_type).select("version_num").head()
|
|
158
|
+
|
|
159
|
+
|
|
152
160
|
def get_unapplied_migrations_list(spark, migrations_dir, migration_type, cat: str, schema: str):
|
|
153
161
|
"""the tail of one chain after the revision VERSION_TABLE records for it.
|
|
154
162
|
|
|
155
163
|
the whole chain when the table is missing or holds no row for this type.
|
|
156
164
|
"""
|
|
157
165
|
ordered = get_migrations_list(migrations_dir)
|
|
158
|
-
|
|
159
|
-
version_table = f"{cat}.{schema}.{VERSION_TABLE}"
|
|
160
|
-
if not spark.catalog.tableExists(version_table):
|
|
161
|
-
return ordered
|
|
162
|
-
|
|
163
|
-
current = (
|
|
164
|
-
spark.read.table(version_table).where(col("migration_type") == migration_type).select("version_num").head()
|
|
165
|
-
)
|
|
166
|
+
current = get_table_version(spark, migration_type, cat, schema)
|
|
166
167
|
if not current:
|
|
167
168
|
return ordered
|
|
168
169
|
|
|
@@ -179,9 +180,6 @@ def get_unapplied_migrations_list(spark, migrations_dir, migration_type, cat: st
|
|
|
179
180
|
|
|
180
181
|
|
|
181
182
|
def create_new_migration(message: str, template_path: str, output_path: str, truncate_slug_length: int = 40):
|
|
182
|
-
"""
|
|
183
|
-
TODO XXX start looking up prev revision id from db or files and including it
|
|
184
|
-
"""
|
|
185
183
|
rev_id = uuid.uuid4().hex[-12:]
|
|
186
184
|
|
|
187
185
|
date_prefix = datetime.datetime.today().strftime("%y%m%d")
|
|
@@ -194,8 +192,15 @@ def create_new_migration(message: str, template_path: str, output_path: str, tru
|
|
|
194
192
|
|
|
195
193
|
migration_path = os.path.join(output_path, migration_filename)
|
|
196
194
|
|
|
195
|
+
try:
|
|
196
|
+
ordered_migrations = get_migrations_list(output_path)
|
|
197
|
+
last_migration_rev_id = ordered_migrations[-1].revision_id if len(ordered_migrations) > 0 else ""
|
|
198
|
+
except ValueError:
|
|
199
|
+
last_migration_rev_id = ""
|
|
200
|
+
|
|
197
201
|
default_migration_content = open(template_path).read()
|
|
198
202
|
default_migration_content = default_migration_content.replace("{{revision_id}}", rev_id)
|
|
203
|
+
default_migration_content = default_migration_content.replace("{{prev_revision_id}}", last_migration_rev_id)
|
|
199
204
|
|
|
200
205
|
with open(migration_path, "w") as migration_file:
|
|
201
206
|
migration_file.write(default_migration_content)
|
|
@@ -288,7 +293,11 @@ def run_migrations(spark, cat, schema, output_folder, migrations_root):
|
|
|
288
293
|
os.makedirs(initial_output_folder, exist_ok=True)
|
|
289
294
|
os.makedirs(dbr_ouput_folder, exist_ok=True)
|
|
290
295
|
os.makedirs(all_spark_ouput_folder, exist_ok=True)
|
|
291
|
-
|
|
296
|
+
version_table = f"{cat}.{schema}.{VERSION_TABLE}"
|
|
297
|
+
if spark.catalog.tableExists(version_table):
|
|
298
|
+
logger.info(f"{version_table} already exists; skipping the initial migrations;")
|
|
299
|
+
else:
|
|
300
|
+
migrate_initial(spark, initial_output_folder, cat, schema)
|
|
292
301
|
if is_dbr():
|
|
293
302
|
migrate_w_rev(spark, dbr_ouput_folder, migrations_root, cat, schema, DBR_ONLY)
|
|
294
303
|
migrate_w_rev(spark, all_spark_ouput_folder, migrations_root, cat, schema, ALL_SPARK)
|
|
@@ -322,7 +331,12 @@ def build_parser(): # pragma: no cover
|
|
|
322
331
|
|
|
323
332
|
p_create = subparsers.add_parser("create_new_migration", help="create a new migration from the template")
|
|
324
333
|
p_create.add_argument("--message", required=True)
|
|
325
|
-
p_create.add_argument(
|
|
334
|
+
p_create.add_argument(
|
|
335
|
+
"--output-path",
|
|
336
|
+
required=True,
|
|
337
|
+
help="the chain directory to write the new migration into. if sql files are in there, the last sql's rev_id"
|
|
338
|
+
"will be set as the new migrations prev_rev_id.",
|
|
339
|
+
)
|
|
326
340
|
p_create.add_argument("--template-path", default=None, help="defaults to the template shipped in this package")
|
|
327
341
|
p_create.set_defaults(func=_cli_create_new_migration)
|
|
328
342
|
|
{spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spark_sql_migrations
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5
|
|
4
4
|
Summary: Chained, idempotent SQL migrations for Spark and Databricks.
|
|
5
5
|
Home-page: https://github.com/mcjug2015/spark_sql_migrations
|
|
6
6
|
Author: Victor Semenov
|
|
@@ -81,10 +81,12 @@ Migrations come from two different owners, and they behave differently:
|
|
|
81
81
|
| **what** | catalog, schema, `_spark_migrations_version` table | your tables and columns |
|
|
82
82
|
| **where** | `spark_sql_migrations/migrations_initial/` | `all_spark_migrations/`, `dbr_only_migrations/` |
|
|
83
83
|
| **selected by** | filename suffix — `_all.sql` everywhere, `_dbr_only.sql` on Databricks | the `prev_revision_id` chain |
|
|
84
|
-
| **when applied** |
|
|
84
|
+
| **when applied** | until the version table exists | once, then recorded |
|
|
85
85
|
|
|
86
|
-
The bootstrap chain is
|
|
87
|
-
|
|
86
|
+
The bootstrap chain is applied on every run until `_spark_migrations_version` exists, and
|
|
87
|
+
skipped from then on. A run that fails partway through bootstrapping replays it, so it must
|
|
88
|
+
still be idempotent. Your own chains are applied once each and their head revision is
|
|
89
|
+
written to the version table.
|
|
88
90
|
|
|
89
91
|
## Laying out your chains
|
|
90
92
|
|
|
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.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/spark_sql/__init__.py
RENAMED
|
File without changes
|
{spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations/spark_utils.py
RENAMED
|
File without changes
|
{spark_sql_migrations-0.0.3 → spark_sql_migrations-0.0.5}/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.3 → spark_sql_migrations-0.0.5}/spark_sql_migrations.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|