def test_data_block_methods(): env = make_test_env() db = DataBlockMetadata( id=get_datablock_id(), inferred_schema_key="_test.TestSchema1", nominal_schema_key="_test.TestSchema2", realized_schema_key="_test.TestSchema3", ) strg = env.get_default_local_python_storage() records = [{"a": 1}] mdr = as_records(records) sdb = StoredDataBlockMetadata( id=get_datablock_id(), data_block_id=db.id, data_block=db, storage_url=strg.url, data_format=RecordsFormat, ) with env.session_scope() as sess: sess.add(db) sess.add(sdb) assert sdb.name is None name = sdb.get_name() assert len(name) > 10 assert sdb.name == name strg.get_api().put(sdb.name, mdr) assert db.inferred_schema(env, sess) == TestSchema1 assert db.nominal_schema(env, sess) == TestSchema2 assert db.realized_schema(env, sess) == TestSchema3 db.compute_record_count() assert db.record_count == 1
def convert_sdb( env: Environment, sess: Session, sdb: StoredDataBlockMetadata, conversion_path: ConversionPath, target_storage: Storage, storages: Optional[List[Storage]] = None, ) -> StoredDataBlockMetadata: if not conversion_path.conversions: return sdb if storages is None: storages = env.storages prev_sdb = sdb next_sdb: Optional[StoredDataBlockMetadata] = None prev_storage = sdb.storage next_storage: Optional[Storage] = None realized_schema = sdb.realized_schema(env, sess) for conversion_edge in conversion_path.conversions: conversion = conversion_edge.conversion target_storage_format = conversion.to_storage_format next_storage = select_storage(target_storage, storages, target_storage_format) logger.debug( f"CONVERSION: {conversion.from_storage_format} -> {conversion.to_storage_format}" ) next_sdb = StoredDataBlockMetadata( # type: ignore id=get_datablock_id(), data_block_id=prev_sdb.data_block_id, data_block=prev_sdb.data_block, data_format=target_storage_format.data_format, storage_url=next_storage.url, ) sess.add(next_sdb) conversion_edge.copier.copy( from_name=prev_sdb.get_name(), to_name=next_sdb.get_name(), conversion=conversion, from_storage_api=prev_storage.get_api(), to_storage_api=next_storage.get_api(), schema=realized_schema, ) if (prev_sdb.data_format.is_python_format() and not prev_sdb.data_format.is_storable()): # If the records obj is in python and not storable, and we just used it, then it can be reused # TODO: Bit of a hack. Is there a central place we can do this? # also is reusable a better name than storable? prev_storage.get_api().remove(prev_sdb.get_name()) prev_sdb.data_block.stored_data_blocks.remove(prev_sdb) if prev_sdb in sess.new: sess.expunge(prev_sdb) else: sess.delete(prev_sdb) prev_sdb = next_sdb prev_storage = next_storage return next_sdb