"""db.py. Database level utility class for testing against the artist_info schema. """ from functools import wraps import sys import boto3 from product import config from product.connectors import mysql from product.connectors.mysql import db_session from product.models.release_approval_queue import ReleaseApprovalQueue from product.models.track_artist import TrackArtist from product.models.track_artist_localized_metadata import \ TrackArtistLocalizedMetadata from product.models.track_localized_metadata import TrackLocalizedMetadata from product.models.track_master_rights import TrackMasterRights from product.models.track_writer import TrackWriter DROP_TABLE_UPCS = """ DROP TABLE IF EXISTS upcs; """ DROP_TABLE_ITUNES_LANGUAGES = """ DROP TABLE IF EXISTS itunes_languages; """ CREATE_TABLE_UPCS = """ CREATE TABLE `upcs` ( `upc` BIGINT(20) PRIMARY KEY, `status` TEXT NOT NULL DEFAULT 'unused', `last_updated` DATETIME NOT NULL); """ CREATE_TABLE_ITUNES_LANGUAGES = """ CREATE TABLE `itunes_languages` ( `language_id` int(10) PRIMARY KEY, `language` TEXT DEFAULT NULL, `language_code` TEXT DEFAULT NULL); """ CREATE_LANGUAGE_TABLE = """ CREATE TABLE `language` ( `language_code` TEXT NOT NULL PRIMARY KEY, `language` TEXT NOT NULL, `iso_639_1_code` varchar(2) DEFAULT NULL ) """ DROP_LANGUAGE_TABLE = 'DROP TABLE IF EXISTS `language`' def drop_vw_product_table(): """DROP `vw_product`.""" DROP_TABLE_PRODUCT = """ DROP TABLE IF EXISTS vw_product """ with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_PRODUCT) def create_vw_product_table_format_and_artist_name(): """Create `vw_product` table, which is actually a SQL view.""" CREATE_TABLE_PRODUCT = """ CREATE TABLE `vw_product` ( `release_id` INTEGER PRIMARY KEY, `upc` INTEGER NOT NULL, `display_upc` TEXT NOT NULL, `deletions` TEXT, `subaccount_id` INTEGER DEFAULT 0, `distribution_format_id` INTEGER DEFAULT NULL, `product_type_id` INTEGER DEFAULT 1, `project_id` INTEGER DEFAULT NULL, `product_code` TEXT DEFAULT NULL, `vendor_id` INTEGER DEFAULT 0, `context_type` TEXT, `release_name` TEXT DEFAULT NULL, `release_status` TEXT NOT NULL DEFAULT 'label_processing', `release_date` DATE DEFAULT NULL, `format` TEXT DEFAULT NULL, `artist_name` TEXT, `not_for_distribution` TEXT); """ with db_session() as session: _exit_if_not_test_environment(session) drop_vw_product_table() session.execute(CREATE_TABLE_PRODUCT) INSERT_PRODUCT_FORMAT_ARTIST_NAME = """ INSERT INTO vw_product( release_id, upc, subaccount_id, distribution_format_id, product_type_id, project_id, vendor_id, context_type, product_code, deletions, display_upc, release_status, release_date, release_name, format, artist_name, not_for_distribution ) VALUES ( 1, 888831283041, 1, 2, 1, 22, 1, 'physical', 'prod-code', 'N', '888831283041', 'label_processing', '2017-09-09', 'product test 1', 'Full Length', 'Artist 3', 'N' ), ( 2, 888831283042, NULL, 1, 1, 33, 1, 'digital', 'prod-code-2', 'N', '888831283042', 'label_processing', '2017-09-17', 'product test 2', 'EP', 'Dino Felipe', 'N' ); """ def create_vw_product_table(): """Create `vw_product` table, which is actually a SQL view.""" CREATE_TABLE_PRODUCT = """ CREATE TABLE `vw_product` ( `release_id` INTEGER PRIMARY KEY, `upc` INTEGER NOT NULL, `display_upc` TEXT NOT NULL, `deletions` TEXT, `format` TEXT DEFAULT NULL, `artist_name` TEXT DEFAULT NULL, `subaccount_id` INTEGER DEFAULT 0, `distribution_format_id` INTEGER DEFAULT NULL, `product_type_id` INTEGER DEFAULT 1, `project_id` INTEGER DEFAULT NULL, `product_code` TEXT DEFAULT NULL, `vendor_id` INTEGER DEFAULT 0, `context_type` TEXT, `release_name` TEXT DEFAULT NULL, `release_status` TEXT NOT NULL DEFAULT 'label_processing', `release_date` DATE DEFAULT NULL, `not_for_distribution` TEXT); """ with db_session() as session: _exit_if_not_test_environment(session) drop_vw_product_table() session.execute(CREATE_TABLE_PRODUCT) INSERT_PRODUCT = """ INSERT INTO vw_product( release_id, upc, subaccount_id, distribution_format_id, product_type_id, project_id, vendor_id, context_type, product_code, deletions, display_upc, release_status, release_date, release_name, not_for_distribution ) VALUES ( 1, 888831283041, 1, 2, 1, 22, 1, 'physical', 'prod-code', 'N', '888831283041', 'label_processing', '2017-09-09', 'product test 1', 'N' ), ( 32123, 1234567654321, 55, 1, 1, 22, 55, 'digital', 'code-cool', 'N', '1234567654321', 'label_processing', '2017-09-09', 'product test XIV', 'N' ), ( 2, 888831283042, NULL, 1, 1, 33, 1, 'digital', 'prod-code-2', 'N', '888831283042', 'label_processing', '2017-09-17', 'product test 2', 'N' ), ( 3, 888831283043, NULL, 2, 1, 33, 1, 'digital', 'prod-code-3', 'N', '888831283043', 'label_processing', '2017-09-17', 'product test 3', 'N' ), ( 89, 888831283044, 5, 2, 1, 33, 8, 'digital', 'prod-code-something', 'N', '888831283044', 'label_processing', '2017-09-09', 'product test 89', 'N' ), ( 90, 888831283045, 8, 2, 1, 33, 5, 'digital', 'prod-code-something', 'N', '888831283045', 'label_processing', '2017-09-17', 'product test 90', 'N' ), ( 91, 888831283046, 5, 2, 1, 33, 8, 'digital', 'prod-code-something-twice', 'N', '888831283046', 'label_processing', '2017-09-09', 'product test 91', 'N' ), ( 92, 888831283047, 5, 2, 1, 33, 1234, 'digital', 'prod-code-something-again', 'N', '888831283047', 'in_content', '2017-09-17', 'product test 92', 'N' ), ( 93, 888831283048, NULL, 2, 1, 33, 1234, 'physical', 'prod-code-something-twice', 'N', '888831283048', 'label_processing', '2017-09-17', 'product test 93', 'N' ), ( 94, 888831283049, NULL, 2, 1, 33, 1234, 'physical', 'prod-code-something-twice', 'Y', '888831283049', 'label_processing', '2017-09-17', 'product test 94', 'N' ), ( 10, 888831283123, NULL, 2, 1, 22, 1234, 'physical', 'prod-code-mt', 'Y', '888831283123', 'label_processing', NULL, 'product test 10', 'N' ), ( 2078461, 191773455477, 1, 2, 1, 33, 1234, 'physical', 'prod-code-something-twice', 'Y', '191773455477', 'label_processing', '2017-09-17', 'product test 2078461', 'N' ), ( 2078459, 191773455453, 1, 2, 1, 22, 1234, 'physical', 'prod-code-mt', 'Y', '191773455453', 'label_processing', NULL, 'product test 2078459', 'N' ), ( 2706033, 194491403904, NULL, 1, 1, 4455, 7123, 'digital', 'P24', 'Y', '194491403904', 'orchard_processing', '2010-08-03', 'Release 1', 'N' ) """ INSERT_DATE_FILTER_PRODUCT = """ INSERT INTO vw_product( release_id, upc, subaccount_id, distribution_format_id, product_type_id, project_id, vendor_id, context_type, product_code, deletions, display_upc, release_status, release_date, release_name, not_for_distribution ) VALUES ( 99, 888831283047, 5, 2, 1, 33, 1234, 'digital', 'prod-code-something-twice', 'N', '888831283047', 'in_content', '2018-12-01', 'product test 92', 'N' ) """ INSERT_DATE_SORT_PRODUCT = """ INSERT INTO vw_product( release_id, upc, subaccount_id, distribution_format_id, product_type_id, project_id, vendor_id, context_type, product_code, deletions, display_upc, release_status, release_date, release_name, not_for_distribution ) VALUES ( 99, 888831283047, 5, 2, 1, 33, 1234, 'digital', 'prod-code-something-twice', 'N', '888831283047', 'in_content', '2018-12-01', 'product test 92', 'N' ), ( 100, 888831283048, 5, 2, 1, 33, 1234, 'digital', 'prod-code-something-twice', 'N', '888831283048', 'in_content', '2018-12-02', 'product test 100', 'N' ) """ INSERT_ITUNES_LANGUAGES = """ INSERT INTO itunes_languages (language_id, language, language_code) VALUES (1, 'Test Language', 'test'); """ INSERT_DUPLICATE_UPC_PRODUCT = """ INSERT INTO vw_product( release_id, upc, subaccount_id, distribution_format_id, product_type_id, project_id, vendor_id, context_type, product_code, deletions, display_upc, not_for_distribution ) VALUES ( 4, 888831283041, 1, 2, 1, 22, 1, 'physical', 'abc-123', 'N', '888831283041', 'N' ) """ INSERT_DELETED_DUPLICATE_UPC_PRODUCT = """ INSERT INTO vw_product( release_id, upc, subaccount_id, distribution_format_id, product_type_id, project_id, vendor_id, context_type, product_code, deletions, display_upc, not_for_distribution ) VALUES ( 4, 888831283041, 1, 2, 1, 22, 1, 'physical', 'abc-123', 'Y', '888831283041', 'N' ) """ def drop_product_type_table(): """DROP `product_type`.""" DROP_TABLE_PRODUCT = """ DROP TABLE IF EXISTS product_type """ with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_PRODUCT) def create_product_type_table(): """Create `product_type` table, which is actually a SQL view.""" CREATE_TABLE_PRODUCT = """ CREATE TABLE `product_type` ( `id` INTEGER PRIMARY KEY, `product_type` TEXT NOT NULL); """ with db_session() as session: _exit_if_not_test_environment(session) drop_product_type_table() session.execute(CREATE_TABLE_PRODUCT) INSERT_PRODUCT_TYPE = """ INSERT INTO product_type (id, product_type) VALUES (1, 'Music'), (2, 'TV Show'), (3, 'Movie'); """ INSERT_RELEASE_SUBGENRE = """ INSERT INTO release_subgenre (id, upc, subgenre_id, release_id) VALUES (1, 123456789, 2, 3); """ INSERT_RELEASE_ARTIST = """ INSERT INTO release_artist (release_artist_id, upc, role, release_id, artist_name, url, artist_info_id) VALUES (1, 123456789, 'performer', 2, 'Charlie', 'url', 123); """ CREATE_TABLE_PLACEHOLDER_UPC = """ CREATE TABLE `placeholder_upc` ( `upc` int(20) PRIMARY KEY ); """ DROP_TABLE_PLACEHOLDER_UPC = """ DROP TABLE IF EXISTS placeholder_upc; """ def create_track_localized_metadata(): """Create Track Localization tables in testing DB.""" TrackLocalizedMetadata.__table__.create(mysql._db_engine) TrackArtist.__table__.create(mysql._db_engine) TrackArtistLocalizedMetadata.__table__.create(mysql._db_engine) def drop_track_localized_metadata(): """Delete Track Localization tables from testing DB.""" TrackLocalizedMetadata.__table__.drop(mysql._db_engine) TrackArtist.__table__.drop(mysql._db_engine) TrackArtistLocalizedMetadata.__table__.drop(mysql._db_engine) def test_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_vw_product_table() create_product_type_table() create_upcs_table() create_itunes_languages() create_language_table() create_release_localized_metadata_table() create_release_artist_localized_metadata_table() create_track_localized_metadata() create_placeholder_upc_table() create_release_artist_table() create_release_asset_version_table() create_release_subgenre_table() create_vendor_table() create_subaccount_table() create_release_approval_queue_table() create_track_writer_table() create_track_master_rights_table() try: function_return = function(*args, **kwargs) finally: drop_vw_product_table() drop_product_type_table() drop_upcs_table() drop_itunes_languages() drop_language_table() drop_release_localized_metadata_table() drop_release_artist_localized_metadata_table() drop_track_localized_metadata() drop_placeholder_upc_table() drop_release_artist_table() drop_release_asset_version_table() drop_release_subgenre_table() drop_vendor_table() drop_subaccount_table() drop_release_approval_queue_table() drop_track_writer_table() drop_track_master_rights_table() return function_return return call_function_within_db_context def seed_models(models): """Save the given model(s) to the DB.""" if not hasattr(models, '__iter__'): models = [models] with db_session() as session: _exit_if_not_test_environment(session) for model in models: session.merge(model) session.commit() def insert_vw_product(query=INSERT_PRODUCT): """Insert data into vw_product table.""" with db_session() as session: session.execute(query) def insert_release_subgenre(): """Insert data into vw_product table.""" with db_session() as session: session.execute(INSERT_RELEASE_SUBGENRE) def insert_release_artist(): """Insert data into vw_product table.""" with db_session() as session: session.execute(INSERT_RELEASE_ARTIST) def insert_product_type(): """Insert data into product_type table.""" with db_session() as session: session.execute(INSERT_PRODUCT_TYPE) def insert_duplicate_vw_product(): """Insert data into vw_product table.""" with db_session() as session: session.execute(INSERT_DUPLICATE_UPC_PRODUCT) def insert_deleted_duplicate_vw_product(): """Insert data into vw_product table.""" with db_session() as session: session.execute(INSERT_DELETED_DUPLICATE_UPC_PRODUCT) def insert_itunes_languages(): """Insert data into itunes_languages table.""" with db_session() as session: session.execute(INSERT_ITUNES_LANGUAGES) def drop_upcs_table(): """Drop the `upcs` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_UPCS) def drop_itunes_languages(): """Drop the `itunes_languages` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_ITUNES_LANGUAGES) def create_upcs_table(): """Create the `upcs` table.""" with db_session() as session: _exit_if_not_test_environment(session) drop_upcs_table() session.execute(CREATE_TABLE_UPCS) def create_itunes_languages(): """Create the `itunes_languages` table.""" with db_session() as session: _exit_if_not_test_environment(session) drop_itunes_languages() session.execute(CREATE_TABLE_ITUNES_LANGUAGES) 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('Environment must be set to {}.'.format( config.TEST_ENVIRONMENT)) if 'sqlite' not in session.bind.url.drivername: sys.exit('Tests must point to sqlite database.') def create_placeholder_upc_table(): """Create the `placeholder_upc` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_TABLE_PLACEHOLDER_UPC) def drop_placeholder_upc_table(): """Drop the `placeholder_upc` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_PLACEHOLDER_UPC) def create_release_artist_table(): """Create the `release_artist` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_TABLE_RELEASE_ARTIST) def create_release_asset_version_table(): """Create the `release_asset_version` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_TABLE_RELEASE_ASSET_VERSION) def drop_release_artist_table(): """Drop the `release_artist` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_RELEASE_ARTIST) def drop_release_asset_version_table(): """Drop the `release_asset_version` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_RELEASE_ASSET_VERSION) def create_release_subgenre_table(): """Create the `release_subgenre` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_TABLE_RELEASE_SUBGENRE) def drop_release_subgenre_table(): """Drop the `release_subgenre` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_RELEASE_SUBGENRE) def create_release_approval_queue_table(): """Create the `release_approval_queue` table.""" ReleaseApprovalQueue.__table__.create(mysql._db_engine) def drop_release_approval_queue_table(): """Drop the `release_approval_queue` table.""" ReleaseApprovalQueue.__table__.drop(mysql._db_engine) def create_track_master_rights_table(): """Create the `track_master_rights` table.""" TrackMasterRights.__table__.create(mysql._db_engine) def drop_track_master_rights_table(): """Drop the `track_master_rights` table.""" TrackMasterRights.__table__.drop(mysql._db_engine) def create_track_writer_table(): """Create the `track_writer` table.""" TrackWriter.__table__.create(mysql._db_engine) def drop_track_writer_table(): """Drop the `track_writer` table.""" TrackWriter.__table__.drop(mysql._db_engine) CREATE_TABLE_RELEASE_ARTIST = """ CREATE TABLE `release_artist` ( `release_artist_id` int(10) PRIMARY KEY, `upc` bigint(20)NOT NULL, `role` varchar(25) NOT NULL DEFAULT 'performer', `release_id` int(11) , `artist_name` varchar(255) NOT NULL, `url` varchar(156) DEFAULT NULL, `artist_info_id` int(10) DEFAULT NULL ); """ CREATE_TABLE_RELEASE_ASSET_VERSION = """ CREATE TABLE `release_asset_version` ( `release_id` int(10) NOT NULL PRIMARY KEY, `api_version` varchar(255) DEFAULT 'v2' ); """ DROP_TABLE_RELEASE_ARTIST = """ DROP TABLE IF EXISTS release_artist; """ DROP_TABLE_RELEASE_ASSET_VERSION = """ DROP TABLE IF EXISTS release_asset_version; """ CREATE_TABLE_RELEASE_SUBGENRE = """ CREATE TABLE `release_subgenre` ( `id` int(10) PRIMARY KEY, `upc` bigint(20) DEFAULT NULL, `subgenre_id` smallint(5) NOT NULL, `release_id` int(11) NOT NULL ); """ DROP_TABLE_RELEASE_SUBGENRE = """ DROP TABLE IF EXISTS release_subgenre; """ CREATE_TABLE_RELEASE_ARTIST_LOCALIZED_METADATA = """ CREATE TABLE `release_artist_localized_metadata` ( `id` int(10) PRIMARY KEY, `release_artist_id` int(11) , `language_id` int(11) , `artist_name` varchar(255) NOT NULL ); """ DROP_TABLE_RELEASE_ARTIST_LOCALIZED_METADATA = """ DROP TABLE IF EXISTS release_artist_localized_metadata; """ INSERT_RELEASE_ARTIST_LOCALIZED_METADATA = """ INSERT INTO release_artist_localized_metadata (id, release_artist_id, language_id, artist_name) VALUES (1, 1, 1, 'performer 1'), (2, 1, 2, 'composer 1'), (3, 2, 1, 'composer 2'), (4, 2, 2, 'performer music1'); """ def create_release_artist_localized_metadata_table(): """Create the `release_artist_localized_metadata` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_TABLE_RELEASE_ARTIST_LOCALIZED_METADATA) def drop_release_artist_localized_metadata_table(): """Drop the `release_artist_localized_metadata` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_RELEASE_ARTIST_LOCALIZED_METADATA) def create_language_table(): """Create the `language` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_LANGUAGE_TABLE) def drop_language_table(): """Create the `language` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_LANGUAGE_TABLE) def insert_release_artist_localized_metadata(): """Insert data into release_artist_localized_metadata table.""" with db_session() as session: session.execute(INSERT_RELEASE_ARTIST_LOCALIZED_METADATA) def create_release_localized_metadata_table(): """Create the `release_localized_metadata` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_TABLE_RELEASE_LOCALIZED_METADATA) def drop_release_localized_metadata_table(): """Drop the `release_localized_metadata` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_RELEASE_LOCALIZED_METADATA) CREATE_TABLE_RELEASE_LOCALIZED_METADATA = """ CREATE TABLE `release_localized_metadata` ( `id` int(10) PRIMARY KEY, `release_id` int(11) , `language_id` int(11) , `release_name` varchar(255), `delivered_version` varchar(255) ); """ DROP_TABLE_RELEASE_LOCALIZED_METADATA = """ DROP TABLE IF EXISTS release_localized_metadata; """ CREATE_TABLE_VENDOR = """ CREATE TABLE `vendor` ( `vendor_id` int PRIMARY KEY, `name` varchar(100), `vendor_uuid` char(36) ); """ INSERT_VENDOR = """ INSERT INTO vendor (vendor_id, name, vendor_uuid) VALUES (1, 'test vendor 1', '51be2aab-33c4-4822-b983-a7b6a4fb33f1'), (5, 'test vendor 5', '272ee023-ac60-47aa-b3da-69b8330b2e41'), (8, 'test vendor 8', '7851e7af-3b16-4648-a69e-aaf33596a8c6'), (55, 'test vendor 55', '4c746eaf-893c-4165-89b3-3faf8c655c1f'), (1234, 'test vendor 1234', 'f372bfe8-c07d-4389-9ff1-3b250dac7c5a'), (7123, 'test vendor 7123', 'd1e6c7b5-0ad7-45a7-8935-3051bc1d2c6c'); """ DROP_TABLE_VENDOR = """ DROP TABLE IF EXISTS vendor; """ def create_vendor_table(): """Create the `vendor` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_TABLE_VENDOR) def insert_vendor(): """Insert data into vendor table.""" with db_session() as session: session.execute(INSERT_VENDOR) def drop_vendor_table(): """Drop the `vendor` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_VENDOR) CREATE_TABLE_SUBACCOUNT = """ CREATE TABLE `subaccount` ( `subaccount_id` int PRIMARY KEY, `vendor_id` int, `subaccount_name` varchar(255), `subaccount_uuid` char(36) ); """ INSERT_SUBACCOUNT = """ INSERT INTO subaccount (subaccount_id, vendor_id, subaccount_name, subaccount_uuid) VALUES (1, 1, 'test subaccount 1', '1203b88e-781d-4fd9-9bd9-0368999abd52'), (55, 1, 'test subaccount 55', '9d6715ca-cdec-43ab-b6a1-0e7e8ed2926c'), (8, 5, 'test subaccount 8', '488c8115-224a-421d-a0c2-6aeb0aab18a6'), (5, 8, 'test subaccount 5', '97218691-610b-441a-9822-45a1e11a1b49'); """ DROP_TABLE_SUBACCOUNT = """ DROP TABLE IF EXISTS subaccount; """ def create_subaccount_table(): """Create the `subaccount` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(CREATE_TABLE_SUBACCOUNT) def insert_subaccount(): """Insert data into subaccount table.""" with db_session() as session: session.execute(INSERT_SUBACCOUNT) def drop_subaccount_table(): """Drop the `subaccount` table.""" with db_session() as session: _exit_if_not_test_environment(session) session.execute(DROP_TABLE_SUBACCOUNT) def create_product_localization_table(): """Create product_localization dynamoDb table.""" client = boto3.client('dynamodb', region_name='us-east-1') client.create_table( TableName='test-product_localization', KeySchema=[ { 'AttributeName': 'product_id', 'KeyType': 'HASH' # Partition key }, { 'AttributeName': 'language_id', 'KeyType': 'RANGE' # Sort key } ], AttributeDefinitions=[ { 'AttributeName': 'product_id', 'AttributeType': 'N' }, { 'AttributeName': 'language_id', 'AttributeType': 'N' } ], ProvisionedThroughput={ 'ReadCapacityUnits': 10, 'WriteCapacityUnits': 10 }) def drop_product_localization_table(): """Drop product_localization dynamoDb table.""" client = boto3.client('dynamodb', region_name='us-east-1') client.delete_table('test-product_localization') def seed_dynamodb_models(models): """Save the given model(s) to the DB.""" if not hasattr(models, '__iter__'): models = [models] for model in models: model.save()