Skip to content

Commit de2bca1

Browse files
sfc-gh-tmathewpodungsfc-gh-twhite
authored
Configure Snowflake Schema via Config (#210) (#211)
* Update issue templates (#206) * Update issue templates: Bug Report, Questions and Enhancement templates * Create CONTRIBUTING.md Initial workflow for contributing to schemachange repository * Add support for specifying the schema via config * Documentation: Include details on configuring the default schema * Updated version and changelog --------- Co-authored-by: podung <joe.depung@gmail.com> Co-authored-by: Tyler White <90005851+sfc-gh-twhite@users.noreply.github.com>
1 parent 9cc82a8 commit de2bca1

File tree

5 files changed

+30
-11
lines changed

5 files changed

+30
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
33

44
*The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).*
55

6+
## [3.6.1] - 2023-11-15
7+
### Added
8+
- Allow passing snowflake schema as config or CLI parameter
9+
610
## [3.6.0] - 2023-09-06
711
### Changed
812
- Fixed bug introduced in version 3.5.0 where the session state was not reset after a user script was run. This resulted in schemachange updates to the metadata table failing in some cases. schemachange will now reset the session back to the default settings after each user script is run

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ snowflake-warehouse: 'warehouse'
307307
# The name of the default database to use. Can be overridden in the change scripts.
308308
snowflake-database: null
309309
310+
# The name of the default schema to use. Can be overridden in the change scripts.
311+
snowflake-schema: null
312+
310313
# Used to override the default name of the change history table (the default is METADATA.SCHEMACHANGE.CHANGE_HISTORY)
311314
change-history-table: null
312315
@@ -374,7 +377,7 @@ Schemachange supports a number of subcommands, it the subcommand is not provided
374377
#### deploy
375378
This is the main command that runs the deployment process.
376379

377-
`usage: schemachange deploy [-h] [--config-folder CONFIG_FOLDER] [-f ROOT_FOLDER] [-m MODULES_FOLDER] [-a SNOWFLAKE_ACCOUNT] [-u SNOWFLAKE_USER] [-r SNOWFLAKE_ROLE] [-w SNOWFLAKE_WAREHOUSE] [-d SNOWFLAKE_DATABASE] [-c CHANGE_HISTORY_TABLE] [--vars VARS] [--create-change-history-table] [-ac] [-v] [--dry-run] [--query-tag QUERY_TAG]`
380+
`usage: schemachange deploy [-h] [--config-folder CONFIG_FOLDER] [-f ROOT_FOLDER] [-m MODULES_FOLDER] [-a SNOWFLAKE_ACCOUNT] [-u SNOWFLAKE_USER] [-r SNOWFLAKE_ROLE] [-w SNOWFLAKE_WAREHOUSE] [-d SNOWFLAKE_DATABASE] [-s SNOWFLAKE_SCHEMA] [-c CHANGE_HISTORY_TABLE] [--vars VARS] [--create-change-history-table] [-ac] [-v] [--dry-run] [--query-tag QUERY_TAG]`
378381

379382
Parameter | Description
380383
--- | ---
@@ -387,6 +390,7 @@ Parameter | Description
387390
-r SNOWFLAKE_ROLE, --snowflake-role SNOWFLAKE_ROLE | The name of the role to use
388391
-w SNOWFLAKE_WAREHOUSE, --snowflake-warehouse SNOWFLAKE_WAREHOUSE | The name of the default warehouse to use. Can be overridden in the change scripts.
389392
-d SNOWFLAKE_DATABASE, --snowflake-database SNOWFLAKE_DATABASE | The name of the default database to use. Can be overridden in the change scripts.
393+
-s SNOWFLAKE_SCHEMA, --snowflake-schema SNOWFLAKE_SCHEMA | The name of the default schema to use. Can be overridden in the change scripts.
390394
-c CHANGE_HISTORY_TABLE, --change-history-table CHANGE_HISTORY_TABLE | Used to override the default name of the change history table (which is METADATA.SCHEMACHANGE.CHANGE_HISTORY)
391395
--vars VARS | Define values for the variables to replaced in change scripts, given in JSON format (e.g. '{"variable1": "value1", "variable2": "value2"}')
392396
--create-change-history-table | Create the change history table if it does not exist. The default is 'False'.
@@ -429,13 +433,13 @@ In order to run schemachange you must have the following:
429433
schemachange is a single python script located at [schemachange/cli.py](schemachange/cli.py). It can be executed as follows:
430434

431435
```
432-
python schemachange/cli.py [-h] [--config-folder CONFIG_FOLDER] [-f ROOT_FOLDER] [-a SNOWFLAKE_ACCOUNT] [-u SNOWFLAKE_USER] [-r SNOWFLAKE_ROLE] [-w SNOWFLAKE_WAREHOUSE] [-d SNOWFLAKE_DATABASE] [-c CHANGE_HISTORY_TABLE] [--vars VARS] [--create-change-history-table] [-ac] [-v] [--dry-run] [--query-tag QUERY_TAG] [--oauth-config OUATH_CONFIG]
436+
python schemachange/cli.py [-h] [--config-folder CONFIG_FOLDER] [-f ROOT_FOLDER] [-a SNOWFLAKE_ACCOUNT] [-u SNOWFLAKE_USER] [-r SNOWFLAKE_ROLE] [-w SNOWFLAKE_WAREHOUSE] [-d SNOWFLAKE_DATABASE] [-s SNOWFLAKE_SCHEMA] [-c CHANGE_HISTORY_TABLE] [--vars VARS] [--create-change-history-table] [-ac] [-v] [--dry-run] [--query-tag QUERY_TAG] [--oauth-config OUATH_CONFIG]
433437
```
434438

435439
Or if installed via `pip`, it can be executed as follows:
436440

437441
```
438-
schemachange [-h] [--config-folder CONFIG_FOLDER] [-f ROOT_FOLDER] [-a SNOWFLAKE_ACCOUNT] [-u SNOWFLAKE_USER] [-r SNOWFLAKE_ROLE] [-w SNOWFLAKE_WAREHOUSE] [-d SNOWFLAKE_DATABASE] [-c CHANGE_HISTORY_TABLE] [--vars VARS] [--create-change-history-table] [-ac] [-v] [--dry-run] [--query-tag QUERY_TAG] [--oauth-config OUATH_CONFIG]
442+
schemachange [-h] [--config-folder CONFIG_FOLDER] [-f ROOT_FOLDER] [-a SNOWFLAKE_ACCOUNT] [-u SNOWFLAKE_USER] [-r SNOWFLAKE_ROLE] [-w SNOWFLAKE_WAREHOUSE] [-d SNOWFLAKE_DATABASE] [-s SNOWFLAKE_SCHEMA] [-c CHANGE_HISTORY_TABLE] [--vars VARS] [--create-change-history-table] [-ac] [-v] [--dry-run] [--query-tag QUERY_TAG] [--oauth-config OUATH_CONFIG]
439443
```
440444

441445
## Getting Started with schemachange
@@ -468,7 +472,7 @@ Here is a sample DevOps development lifecycle with schemachange:
468472
If your build agent has a recent version of python 3 installed, the script can be ran like so:
469473
```
470474
pip install schemachange --upgrade
471-
schemachange [-h] [-f ROOT_FOLDER] -a SNOWFLAKE_ACCOUNT -u SNOWFLAKE_USER -r SNOWFLAKE_ROLE -w SNOWFLAKE_WAREHOUSE [-d SNOWFLAKE_DATABASE] [-c CHANGE_HISTORY_TABLE] [--vars VARS] [--create-change-history-table] [-ac] [-v] [--dry-run] [--query-tag QUERY_TAG] [--oauth-config OUATH_CONFIG]
475+
schemachange [-h] [-f ROOT_FOLDER] -a SNOWFLAKE_ACCOUNT -u SNOWFLAKE_USER -r SNOWFLAKE_ROLE -w SNOWFLAKE_WAREHOUSE [-d SNOWFLAKE_DATABASE] [-s SNOWFLAKE_SCHEMA] [-c CHANGE_HISTORY_TABLE] [--vars VARS] [--create-change-history-table] [-ac] [-v] [--dry-run] [--query-tag QUERY_TAG] [--oauth-config OUATH_CONFIG]
472476
```
473477

474478
Or if you prefer docker, set the environment variables and run like so:

schemachange/cli.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
#region Global Variables
2323
# metadata
24-
_schemachange_version = '3.6.0'
24+
_schemachange_version = '3.6.1'
2525
_config_file_name = 'schemachange-config.yml'
2626
_metadata_database_name = 'METADATA'
2727
_metadata_schema_name = 'SCHEMACHANGE'
@@ -48,7 +48,8 @@
4848
+ "\nSNOWFLAKE_AUTHENTICATOR must be defined is using Oauth, OKTA or external Browser Authentication."
4949
_log_config_details = "Using Snowflake account {snowflake_account}\nUsing default role " \
5050
+ "{snowflake_role}\nUsing default warehouse {snowflake_warehouse}\nUsing default " \
51-
+ "database {snowflake_database}"
51+
+ "database {snowflake_database}" \
52+
+ "schema {snowflake_schema}"
5253
_log_ch_use = "Using change history table {database_name}.{schema_name}.{table_name} " \
5354
+ "(last altered {last_altered})"
5455
_log_ch_create = "Created change history table {database_name}.{schema_name}.{table_name}"
@@ -211,6 +212,7 @@ class SnowflakeSchemachangeSession:
211212
+ "'{status}','{user}',CURRENT_TIMESTAMP);"
212213
_q_set_sess_role = 'USE ROLE {role};'
213214
_q_set_sess_database = 'USE DATABASE {database};'
215+
_q_set_sess_schema = 'USE SCHEMA {schema};'
214216
_q_set_sess_warehouse = 'USE WAREHOUSE {warehouse};'
215217
#endregion Query Templates
216218

@@ -225,7 +227,7 @@ def __init__(self, config):
225227
# Retreive Connection info from config dictionary
226228
self.conArgs = {"user": config['snowflake_user'],"account": config['snowflake_account'] \
227229
,"role": config['snowflake_role'],"warehouse": config['snowflake_warehouse'] \
228-
,"database": config['snowflake_database'],"application": _snowflake_application_name \
230+
,"database": config['snowflake_database'],"schema": config['snowflake_schema'], "application": _snowflake_application_name \
229231
,"session_parameters":session_parameters}
230232

231233
self.oauth_config = config['oauth_config']
@@ -434,6 +436,8 @@ def reset_session(self):
434436
reset_query += self._q_set_sess_warehouse.format(**self.conArgs) + " "
435437
if self.conArgs['database']:
436438
reset_query += self._q_set_sess_database.format(**self.conArgs) + " "
439+
if self.conArgs['schema']:
440+
reset_query += self._q_set_sess_schema.format(**self.conArgs) + " "
437441

438442
self.execute_snowflake_query(reset_query)
439443

@@ -629,7 +633,7 @@ def load_schemachange_config(config_file_path: str) -> Dict[str, Any]:
629633
return config
630634

631635
def get_schemachange_config(config_file_path, root_folder, modules_folder, snowflake_account, \
632-
snowflake_user, snowflake_role, snowflake_warehouse, snowflake_database, \
636+
snowflake_user, snowflake_role, snowflake_warehouse, snowflake_database, snowflake_schema, \
633637
change_history_table, vars, create_change_history_table, autocommit, verbose, \
634638
dry_run, query_tag, oauth_config, **kwargs):
635639

@@ -640,6 +644,7 @@ def get_schemachange_config(config_file_path, root_folder, modules_folder, snowf
640644
"modules_folder":modules_folder, "snowflake_account":snowflake_account, \
641645
"snowflake_user":snowflake_user, "snowflake_role":snowflake_role, \
642646
"snowflake_warehouse":snowflake_warehouse, "snowflake_database":snowflake_database, \
647+
"snowflake_schema":snowflake_schema, \
643648
"change_history_table":change_history_table, "vars":vars, \
644649
"create_change_history_table":create_change_history_table, \
645650
"autocommit":autocommit, "verbose":verbose, "dry_run":dry_run,\
@@ -654,7 +659,8 @@ def get_schemachange_config(config_file_path, root_folder, modules_folder, snowf
654659
# create Default values dictionary
655660
config_defaults = {"root_folder":os.path.abspath('.'), "modules_folder":None, \
656661
"snowflake_account":None, "snowflake_user":None, "snowflake_role":None, \
657-
"snowflake_warehouse":None, "snowflake_database":None, "change_history_table":None, \
662+
"snowflake_warehouse":None, "snowflake_database":None, "snowflake_schema":None, \
663+
"change_history_table":None, \
658664
"vars":{}, "create_change_history_table":False, "autocommit":False, "verbose":False, \
659665
"dry_run":False , "query_tag":None , "oauth_config":None }
660666
#insert defualt values for items not populated
@@ -816,6 +822,7 @@ def main(argv=sys.argv):
816822
parser_deploy.add_argument('-r', '--snowflake-role', type = str, help = 'The name of the default role to use', required = False)
817823
parser_deploy.add_argument('-w', '--snowflake-warehouse', type = str, help = 'The name of the default warehouse to use. Can be overridden in the change scripts.', required = False)
818824
parser_deploy.add_argument('-d', '--snowflake-database', type = str, help = 'The name of the default database to use. Can be overridden in the change scripts.', required = False)
825+
parser_deploy.add_argument('-s', '--snowflake-schema', type = str, help = 'The name of the default schema to use. Can be overridden in the change scripts.', required = False)
819826
parser_deploy.add_argument('-c', '--change-history-table', type = str, help = 'Used to override the default name of the change history table (the default is METADATA.SCHEMACHANGE.CHANGE_HISTORY)', required = False)
820827
parser_deploy.add_argument('--vars', type = json.loads, help = 'Define values for the variables to replaced in change scripts, given in JSON format (e.g. {"variable1": "value1", "variable2": "value2"})', required = False)
821828
parser_deploy.add_argument('--create-change-history-table', action='store_true', help = 'Create the change history schema and table, if they do not exist (the default is False)', required = False)
@@ -855,7 +862,8 @@ def main(argv=sys.argv):
855862
if args.subcommand == 'render':
856863
renderoveride = {"snowflake_account":None,"snowflake_user":None,"snowflake_role":None, \
857864
"snowflake_warehouse":None,"snowflake_database":None,"change_history_table":None, \
858-
"create_change_history_table":None,"autocommit":None,"dry_run":None,"query_tag":None,"oauth_config":None }
865+
"snowflake_schema":None,"create_change_history_table":None,"autocommit":None, \
866+
"dry_run":None,"query_tag":None,"oauth_config":None }
859867
schemachange_args.update(renderoveride)
860868
config = get_schemachange_config(**schemachange_args)
861869

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = schemachange
3-
version = 3.6.0
3+
version = 3.6.1
44
description = A Database Change Management tool for Snowflake
55
long_description = file: README.md
66
long_description_content_type = text/markdown

tests/test_main.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
'snowflake_role':None,
1616
'snowflake_warehouse': None,
1717
'snowflake_database': None,
18+
'snowflake_schema': None,
1819
'change_history_table': None,
1920
'vars': {},
2021
'create_change_history_table': False,
@@ -41,6 +42,8 @@
4142
{**DEFAULT_CONFIG, 'snowflake_warehouse': 'warehouse'}),
4243
(["schemachange", "deploy", "--snowflake-database", "database"],
4344
{**DEFAULT_CONFIG, 'snowflake_database': 'database'}),
45+
(["schemachange", "deploy", "--snowflake-schema", "schema"],
46+
{**DEFAULT_CONFIG, "snowflake_schema": "schema"}),
4447
(["schemachange", "deploy", "--change-history-table", "db.schema.table"],
4548
{**DEFAULT_CONFIG, 'change_history_table': 'db.schema.table'}),
4649
(["schemachange", "deploy", "--vars", '{"var1": "val"}'],

0 commit comments

Comments
 (0)