spark-sql-migrations 0.0.1__tar.gz → 0.0.3__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.1 → spark_sql_migrations-0.0.3}/PKG-INFO +12 -4
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/setup.py +17 -4
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/__init__.py +2 -3
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/spark_sql/spark_sql.py +23 -4
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations.egg-info/PKG-INFO +12 -4
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations.egg-info/SOURCES.txt +1 -1
- spark_sql_migrations-0.0.3/spark_sql_migrations.egg-info/entry_points.txt +2 -0
- spark_sql_migrations-0.0.1/spark_sql_migrations/custom_logging.py +0 -78
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/LICENSE +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/MANIFEST.in +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/backend_shim.py +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/setup.cfg +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/migration_templates/default_migration_template.sql +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/migrations_initial/first_01_intial_create_cat_dbr_only.sql +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/migrations_initial/first_02_intial_create_schema_all.sql +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/migrations_initial/first_03_intial_create_state_table_all.sql +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/py.typed +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/spark_sql/__init__.py +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/spark_utils.py +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations.egg-info/dependency_links.txt +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations.egg-info/namespace_packages.txt +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations.egg-info/requires.txt +0 -0
- {spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/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.3
|
|
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
|
|
@@ -103,9 +103,16 @@ Choose deliberately. SQL that only Databricks understands must not live in
|
|
|
103
103
|
## Running migrations
|
|
104
104
|
|
|
105
105
|
```bash
|
|
106
|
-
|
|
106
|
+
spark-sql-migrations run --cat spark_catalog --schema default --migrations-dir path/to/migrations
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
The command configures logging via `logging.basicConfig()`, so each applied migration is
|
|
110
|
+
logged to stderr at INFO. It leaves an already-configured root logger alone, and every
|
|
111
|
+
other entry point into this library inherits the host application's logging untouched.
|
|
112
|
+
The command needs a Spark flavour installed; it
|
|
113
|
+
fails to import on a bare install. `python -m spark_sql_migrations.spark_sql.spark_sql`
|
|
114
|
+
is equivalent.
|
|
115
|
+
|
|
109
116
|
Or from Python, which is what a consuming project usually wraps:
|
|
110
117
|
|
|
111
118
|
```python
|
|
@@ -122,7 +129,8 @@ def get_migrations_dir():
|
|
|
122
129
|
main(cat="spark_catalog", schema="default", migrations_dir=get_migrations_dir())
|
|
123
130
|
```
|
|
124
131
|
|
|
125
|
-
`main` builds its own session via `get_spark()
|
|
132
|
+
`main` builds its own session via `get_spark()` and, being library code, leaves logging to
|
|
133
|
+
you. To supply your own — a session already
|
|
126
134
|
configured by your job, say — call `run_migrations(spark, cat, schema, output_folder,
|
|
127
135
|
migrations_root)` directly.
|
|
128
136
|
|
|
@@ -134,7 +142,7 @@ before it is executed, so you can always read the exact SQL a run applied.
|
|
|
134
142
|
Generate one rather than hand-rolling the header:
|
|
135
143
|
|
|
136
144
|
```bash
|
|
137
|
-
|
|
145
|
+
spark-sql-migrations create_new_migration --message "add batch id to metrics" --output-path path/to/migrations/all_spark_migrations
|
|
138
146
|
```
|
|
139
147
|
|
|
140
148
|
That writes `<yymmdd>_<slug>_<revision_id>.sql` from the template shipped in the package
|
|
@@ -15,6 +15,11 @@ setup(**{
|
|
|
15
15
|
'Typing :: Typed',
|
|
16
16
|
],
|
|
17
17
|
'description': 'Chained, idempotent SQL migrations for Spark and Databricks.',
|
|
18
|
+
'entry_points': {
|
|
19
|
+
'console_scripts': [
|
|
20
|
+
'spark-sql-migrations = spark_sql_migrations.spark_sql.spark_sql:cli',
|
|
21
|
+
],
|
|
22
|
+
},
|
|
18
23
|
'extras_require': {
|
|
19
24
|
'local': [
|
|
20
25
|
'pyspark[connect]>=4.0,<5',
|
|
@@ -99,12 +104,19 @@ Choose deliberately. SQL that only Databricks understands must not live in
|
|
|
99
104
|
## Running migrations
|
|
100
105
|
|
|
101
106
|
```bash
|
|
102
|
-
|
|
107
|
+
spark-sql-migrations run \
|
|
103
108
|
--cat spark_catalog \
|
|
104
109
|
--schema default \
|
|
105
110
|
--migrations-dir path/to/migrations
|
|
106
111
|
```
|
|
107
112
|
|
|
113
|
+
The command configures logging via `logging.basicConfig()`, so each applied migration is
|
|
114
|
+
logged to stderr at INFO. It leaves an already-configured root logger alone, and every
|
|
115
|
+
other entry point into this library inherits the host application's logging untouched.
|
|
116
|
+
The command needs a Spark flavour installed; it
|
|
117
|
+
fails to import on a bare install. `python -m spark_sql_migrations.spark_sql.spark_sql`
|
|
118
|
+
is equivalent.
|
|
119
|
+
|
|
108
120
|
Or from Python, which is what a consuming project usually wraps:
|
|
109
121
|
|
|
110
122
|
```python
|
|
@@ -121,7 +133,8 @@ def get_migrations_dir():
|
|
|
121
133
|
main(cat="spark_catalog", schema="default", migrations_dir=get_migrations_dir())
|
|
122
134
|
```
|
|
123
135
|
|
|
124
|
-
`main` builds its own session via `get_spark()
|
|
136
|
+
`main` builds its own session via `get_spark()` and, being library code, leaves logging to
|
|
137
|
+
you. To supply your own — a session already
|
|
125
138
|
configured by your job, say — call `run_migrations(spark, cat, schema, output_folder,
|
|
126
139
|
migrations_root)` directly.
|
|
127
140
|
|
|
@@ -133,7 +146,7 @@ before it is executed, so you can always read the exact SQL a run applied.
|
|
|
133
146
|
Generate one rather than hand-rolling the header:
|
|
134
147
|
|
|
135
148
|
```bash
|
|
136
|
-
|
|
149
|
+
spark-sql-migrations create_new_migration \
|
|
137
150
|
--message "add batch id to metrics" \
|
|
138
151
|
--output-path path/to/migrations/all_spark_migrations
|
|
139
152
|
```
|
|
@@ -239,5 +252,5 @@ Apache License 2.0 — see [LICENSE](LICENSE).
|
|
|
239
252
|
},
|
|
240
253
|
'python_requires': '>=3.10',
|
|
241
254
|
'url': 'https://github.com/mcjug2015/spark_sql_migrations',
|
|
242
|
-
'version': '0.0.
|
|
255
|
+
'version': '0.0.3',
|
|
243
256
|
})
|
|
@@ -2,7 +2,6 @@ import logging
|
|
|
2
2
|
|
|
3
3
|
# A library must not configure logging when it is imported. A NullHandler on the
|
|
4
4
|
# package root keeps our records off logging.lastResort while leaving every
|
|
5
|
-
# decision about handlers, levels and formats to the host application
|
|
6
|
-
#
|
|
7
|
-
# spark_sql_migrations.custom_logging.setup_logging() from its own entry point.
|
|
5
|
+
# decision about handlers, levels and formats to the host application, which
|
|
6
|
+
# configures logging from its own entry point.
|
|
8
7
|
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
|
@@ -260,7 +260,11 @@ def record_revision(spark, cat: str, schema: str, migration_type: str, revision_
|
|
|
260
260
|
|
|
261
261
|
|
|
262
262
|
def migrate_w_rev(spark, output_folder, migrations_root, cat: str, schema: str, migration_type: str):
|
|
263
|
-
"""
|
|
263
|
+
"""
|
|
264
|
+
apply the migrations of one client chain that VERSION_TABLE hasn't recorded yet.
|
|
265
|
+
TODO XXX permit applying up to a revision below the head revision
|
|
266
|
+
TODO XXX add backwards migrations, permit migrating backwards
|
|
267
|
+
"""
|
|
264
268
|
migrations_dir = get_migrations_dir(migrations_root, migration_type)
|
|
265
269
|
unapplied = get_unapplied_migrations_list(spark, migrations_dir, migration_type, cat=cat, schema=schema)
|
|
266
270
|
|
|
@@ -325,9 +329,24 @@ def build_parser(): # pragma: no cover
|
|
|
325
329
|
return parser
|
|
326
330
|
|
|
327
331
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
332
|
+
def cli(argv=None): # pragma: no cover
|
|
333
|
+
"""the `spark-sql-migrations` console command.
|
|
334
|
+
|
|
335
|
+
an application entry point, so unlike the rest of this package it configures
|
|
336
|
+
logging. basicConfig is a no-op once the root logger has handlers, which keeps
|
|
337
|
+
this from clobbering a host application that got there first.
|
|
338
|
+
"""
|
|
339
|
+
logging.basicConfig(
|
|
340
|
+
level=logging.INFO,
|
|
341
|
+
format="%(levelname)s %(asctime)s %(name)s : %(message)s",
|
|
342
|
+
datefmt="%y/%m/%d %H:%M:%S",
|
|
343
|
+
)
|
|
344
|
+
logging.getLogger("py4j").setLevel(logging.ERROR)
|
|
345
|
+
kwargs = vars(build_parser().parse_args(argv))
|
|
331
346
|
func = kwargs.pop("func")
|
|
332
347
|
kwargs.pop("command")
|
|
333
348
|
func(**kwargs)
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
if __name__ == "__main__": # pragma: no cover
|
|
352
|
+
cli()
|
{spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/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.3
|
|
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
|
|
@@ -103,9 +103,16 @@ Choose deliberately. SQL that only Databricks understands must not live in
|
|
|
103
103
|
## Running migrations
|
|
104
104
|
|
|
105
105
|
```bash
|
|
106
|
-
|
|
106
|
+
spark-sql-migrations run --cat spark_catalog --schema default --migrations-dir path/to/migrations
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
The command configures logging via `logging.basicConfig()`, so each applied migration is
|
|
110
|
+
logged to stderr at INFO. It leaves an already-configured root logger alone, and every
|
|
111
|
+
other entry point into this library inherits the host application's logging untouched.
|
|
112
|
+
The command needs a Spark flavour installed; it
|
|
113
|
+
fails to import on a bare install. `python -m spark_sql_migrations.spark_sql.spark_sql`
|
|
114
|
+
is equivalent.
|
|
115
|
+
|
|
109
116
|
Or from Python, which is what a consuming project usually wraps:
|
|
110
117
|
|
|
111
118
|
```python
|
|
@@ -122,7 +129,8 @@ def get_migrations_dir():
|
|
|
122
129
|
main(cat="spark_catalog", schema="default", migrations_dir=get_migrations_dir())
|
|
123
130
|
```
|
|
124
131
|
|
|
125
|
-
`main` builds its own session via `get_spark()
|
|
132
|
+
`main` builds its own session via `get_spark()` and, being library code, leaves logging to
|
|
133
|
+
you. To supply your own — a session already
|
|
126
134
|
configured by your job, say — call `run_migrations(spark, cat, schema, output_folder,
|
|
127
135
|
migrations_root)` directly.
|
|
128
136
|
|
|
@@ -134,7 +142,7 @@ before it is executed, so you can always read the exact SQL a run applied.
|
|
|
134
142
|
Generate one rather than hand-rolling the header:
|
|
135
143
|
|
|
136
144
|
```bash
|
|
137
|
-
|
|
145
|
+
spark-sql-migrations create_new_migration --message "add batch id to metrics" --output-path path/to/migrations/all_spark_migrations
|
|
138
146
|
```
|
|
139
147
|
|
|
140
148
|
That writes `<yymmdd>_<slug>_<revision_id>.sql` from the template shipped in the package
|
{spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations.egg-info/SOURCES.txt
RENAMED
|
@@ -3,12 +3,12 @@ MANIFEST.in
|
|
|
3
3
|
backend_shim.py
|
|
4
4
|
setup.py
|
|
5
5
|
spark_sql_migrations/__init__.py
|
|
6
|
-
spark_sql_migrations/custom_logging.py
|
|
7
6
|
spark_sql_migrations/py.typed
|
|
8
7
|
spark_sql_migrations/spark_utils.py
|
|
9
8
|
spark_sql_migrations.egg-info/PKG-INFO
|
|
10
9
|
spark_sql_migrations.egg-info/SOURCES.txt
|
|
11
10
|
spark_sql_migrations.egg-info/dependency_links.txt
|
|
11
|
+
spark_sql_migrations.egg-info/entry_points.txt
|
|
12
12
|
spark_sql_migrations.egg-info/namespace_packages.txt
|
|
13
13
|
spark_sql_migrations.egg-info/requires.txt
|
|
14
14
|
spark_sql_migrations.egg-info/top_level.txt
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
"""Opinionated logging configuration, for *applications* to opt into.
|
|
2
|
-
|
|
3
|
-
Importing spark_sql_migrations never configures logging: library modules take a plain
|
|
4
|
-
``logging.getLogger(__name__)`` and inherit whatever the host application set
|
|
5
|
-
up. An application that wants this format calls :func:`setup_logging` from its
|
|
6
|
-
own entry point -- never at import time, and never from library code, because
|
|
7
|
-
configuring the root logger is the application's decision to make.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import logging.config
|
|
11
|
-
import os
|
|
12
|
-
|
|
13
|
-
LOG_FILE_ENV_VAR = "SPARK_SQL_MIGRATIONS_LOG_FILE"
|
|
14
|
-
DEFAULT_LOG_FILENAME = "local_log.log"
|
|
15
|
-
|
|
16
|
-
FORMAT = "%(levelname)s %(asctime)s %(filename)s->%(funcName)s->%(lineno)d : %(message)s"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def get_log_file_path():
|
|
20
|
-
"""where the file handler writes.
|
|
21
|
-
|
|
22
|
-
resolved against the caller's cwd for the same reason as the spark warehouse
|
|
23
|
-
dir: a __file__-relative default would land inside site-packages once this
|
|
24
|
-
is installed from a wheel.
|
|
25
|
-
"""
|
|
26
|
-
return os.environ.get(LOG_FILE_ENV_VAR, os.path.join(os.getcwd(), DEFAULT_LOG_FILENAME))
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def build_config():
|
|
30
|
-
"""built per call, not a module constant: get_log_file_path() reads the
|
|
31
|
-
environment, and at module-import time the consumer hasn't set it yet."""
|
|
32
|
-
return {
|
|
33
|
-
"version": 1,
|
|
34
|
-
"disable_existing_loggers": False,
|
|
35
|
-
"formatters": {
|
|
36
|
-
"simple": {
|
|
37
|
-
"format": FORMAT,
|
|
38
|
-
"datefmt": "%y/%m/%d %H:%M:%S",
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"handlers": {
|
|
42
|
-
"stdout": {
|
|
43
|
-
"class": "logging.StreamHandler",
|
|
44
|
-
"level": "INFO",
|
|
45
|
-
"formatter": "simple",
|
|
46
|
-
"stream": "ext://sys.stdout",
|
|
47
|
-
},
|
|
48
|
-
"stderr": {
|
|
49
|
-
"class": "logging.StreamHandler",
|
|
50
|
-
"level": "ERROR",
|
|
51
|
-
"formatter": "simple",
|
|
52
|
-
"stream": "ext://sys.stderr",
|
|
53
|
-
},
|
|
54
|
-
"file": {
|
|
55
|
-
"class": "logging.FileHandler",
|
|
56
|
-
"formatter": "simple",
|
|
57
|
-
"filename": get_log_file_path(),
|
|
58
|
-
"mode": "a",
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
"root": {"level": "DEBUG", "handlers": ["stderr", "stdout", "file"]},
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def is_logging_configured():
|
|
66
|
-
# Check if the root logger has any handlers explicitly assigned
|
|
67
|
-
return len(logging.getLogger().handlers) >= 3
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def setup_logging():
|
|
71
|
-
"""configure the root logger with our handlers; safe to call more than once.
|
|
72
|
-
|
|
73
|
-
for application entry points only -- see the module docstring.
|
|
74
|
-
"""
|
|
75
|
-
if not is_logging_configured():
|
|
76
|
-
logging.config.dictConfig(build_config())
|
|
77
|
-
logging.getLogger("py4j").setLevel(logging.ERROR)
|
|
78
|
-
return logging
|
|
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.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/spark_sql/__init__.py
RENAMED
|
File without changes
|
{spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations/spark_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{spark_sql_migrations-0.0.1 → spark_sql_migrations-0.0.3}/spark_sql_migrations.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|