import json import sqlite3 from aws_lambda_powertools import Logger from aws_lambda_powertools.utilities.data_classes import ( EventBridgeEvent, event_source, ) from aws_lambda_powertools.utilities.typing import LambdaContext from glom import glom from layercake.dateutils import now from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey from sqlite_utils import Database from boto3clients import dynamodb_client from config import ( COURSE_TABLE, ENROLLMENT_TABLE, SQLITE_DATABASE, SQLITE_TABLE, USER_TABLE, ) sqlite3.register_converter('json', json.loads) logger = Logger(__name__) enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client) @event_source(data_class=EventBridgeEvent) @logger.inject_lambda_context def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: new_image = event.detail['new_image'] now_ = now() course_id = glom(new_image, 'course.id') data = enrollment_layer.collection.get_items( KeyPair( pk=glom(new_image, 'user.id'), sk=SortKey('konviva', path_spec='konvivaId'), rename_key='user_id', table_name=USER_TABLE, ) + KeyPair( pk=course_id, sk=SortKey('0', path_spec='metadata__konviva_class_id'), table_name=COURSE_TABLE, rename_key='class_id', ), flatten_top=False, ) # If `class_id` is not found, try to retrieve it from the SQLite # migration database. if 'class_id' not in data: data['class_id'] = _get_class_id(course_id) logger.info('IDs found', ids=data) return enrollment_layer.put_item( item={ 'id': new_image['id'], 'sk': 'konviva', 'user_id': data['user_id'], 'class_id': data['class_id'], 'created_at': now_, }, cond_expr='attribute_not_exists(sk)', ) class CourseNotFoundError(Exception): def __init__(self, *args): super().__init__('Course not found in SQLite') # Post-migration: remove the following function def _get_class_id(course_id: str) -> int: with sqlite3.connect( database=SQLITE_DATABASE, detect_types=sqlite3.PARSE_DECLTYPES ) as conn: db = Database(conn) rows = db[SQLITE_TABLE].rows_where( "json->>'$.metadata__betaeducacao_id' = ?", [course_id] ) for row in rows: return int(row['json']['metadata__konviva_id']) logger.error('Course not found', course_id=course_id) raise CourseNotFoundError