"""db.py. Database level utility class for testing against the track_info schema. """ from functools import wraps import sys from product_film import config from product_film.connectors.mysql import db_session DROP_TABLE_TRACK_CROP_INFO = """ DROP TABLE IF EXISTS track_crop_info; """ CREATE_TABLE_TRACK_CROP_INFO = """ CREATE TABLE `track_crop_info` ( `track_id` INT(10), `crop_left` INT(10), `crop_right` INT(10), `crop_top` INT(10), `crop_bottom` INT(10), `orchard_user_id` INT(10), `created_timestamp` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, `updated_timestamp` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ) """ INSERT_TRACK_CROP_INFO_DATA = """ INSERT INTO `track_crop_info`( track_id, crop_left, crop_right, crop_top, crop_bottom, orchard_user_id, created_timestamp, updated_timestamp ) VALUES (1, 10, 11, 10, 11, 1, '2018-04-02 03:32:34', '2018-04-02 03:32:34'), (2, 20, 20, 20, 20, 1, '2018-04-02 03:32:34', '2018-04-02 03:32:34'), (3, 21, 21, 21, 21, 2, '2018-04-02 03:32:34', '2018-04-02 03:32:34') """ def _exit_if_not_test_environment(session): """For safety, only run tests in test environment pointed to sqlite. Exit immediately if not in test environment or not pointed to sqlite. """ if config.ENVIRONMENT != config.TEST_ENVIRONMENT: sys.exit(f'Environment must be set to {config.TEST_ENVIRONMENT!r}.') if 'sqlite' not in session.bind.url.drivername: sys.exit('Tests must point to sqlite database.') def drop_track_crop_info_table(): """DROP `track_crop_info`.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_TRACK_CROP_INFO) def create_track_crop_info_table(): """Create `track_crop_info` table, which is actually a SQL view.""" with db_session() as session: _exit_if_not_test_environment(session) drop_track_crop_info_table() session.execute(CREATE_TABLE_TRACK_CROP_INFO) def insert_track_crop_info_data(): """Insert data into track_crop_info table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(INSERT_TRACK_CROP_INFO_DATA) def create_schema(function): """Create and tear down the test DB schema around a function call. This just creates the schema and does not seed data. Indvidual test cases can use factories to seed data as needed. Args: Function (func): the function to be called after creating the test schema. Returns: Function: The decorated function. """ @wraps(function) def call_function_within_db_context(*args, **kwargs): create_track_crop_info_table() try: function_return = function(*args, **kwargs) return function_return finally: drop_track_crop_info_table() return call_function_within_db_context