def test_cats_and_dogs(self): yaml = """ - object: PetFood nickname: DogFood - object: PetFood nickname: CatFood - object: Person fields: dog: - object: Animal fields: food: reference: DogFood cat: - object: Animal fields: food: reference: CatFood """ summary = generate(StringIO(yaml), {}, None) mapping = mapping_from_recipe_templates(summary) assert len(mapping) == 3 assert "Insert Person" in mapping assert "Insert PetFood" in mapping assert "Insert Animal" in mapping assert mapping["Insert Person"]["sf_object"] == "Person" assert mapping["Insert Person"]["table"] == "Person" assert mapping["Insert Person"]["fields"] == {} assert mapping["Insert Person"]["lookups"]["dog"]["table"] == "Animal" assert mapping["Insert Person"]["lookups"]["dog"]["key_field"] == "dog" assert mapping["Insert Person"]["lookups"]["cat"]["table"] == "Animal" assert mapping["Insert Person"]["lookups"]["cat"]["key_field"] == "cat" assert mapping["Insert PetFood"]["sf_object"] == "PetFood" assert mapping["Insert PetFood"]["table"] == "PetFood" assert mapping["Insert PetFood"]["fields"] == {} assert not mapping["Insert PetFood"].get("lookups") assert mapping["Insert Animal"]["sf_object"] == "Animal" assert mapping["Insert Animal"]["table"] == "Animal" assert mapping["Insert Animal"]["fields"] == {} assert mapping["Insert Animal"]["lookups"]["food"][ "table"] == "PetFood" assert mapping["Insert Animal"]["lookups"]["food"][ "key_field"] == "food"
def test_simple_child_parent_reference(self): yaml = """ - object: Parent friends: - object: Child fields: parent: reference: Parent """ summary = generate(StringIO(yaml), {}, None) mapping = mapping_from_recipe_templates(summary) assert len(mapping) == 2 assert "Insert Parent" in mapping assert "Insert Child" in mapping assert mapping["Insert Parent"]["sf_object"] == "Parent" assert mapping["Insert Parent"]["table"] == "Parent" assert mapping["Insert Parent"]["fields"] == {} assert mapping["Insert Child"]["lookups"]["parent"][ "table"] == "Parent"
def test_nickname_reference(self): yaml = """ - object: Target nickname: bubba - object: Referrer fields: food: shrimp shrimpguy: reference: bubba """ summary = generate(StringIO(yaml), {}, None) mapping = mapping_from_recipe_templates(summary) assert len(mapping) == 2 assert "Insert Target" in mapping assert "Insert Referrer" in mapping assert mapping["Insert Target"]["sf_object"] == "Target" assert mapping["Insert Referrer"]["table"] == "Referrer" assert mapping["Insert Referrer"]["fields"] == {"food": "food"} assert mapping["Insert Referrer"]["lookups"]["shrimpguy"]["table"] == "Target"
def generate_cli( yaml_file, option=[], dburls=[], target_number=None, mapping_file=None, debug_internals=False, generate_cci_mapping_file=None, output_format=None, output_files=None, output_folder=None, nickname_ids=None, continuation_file=None, generate_continuation_file=None, ): """ Generates records from a YAML file \b Records can go to: * stdout (default) * JSON file (--output_format=json --output-file=foo.json) * diagram file (--output_format=png --output-file=foo.png) * a database identified by --dburl (e.g. --dburl sqlite:////tmp/foo.db) * or to a directory as a set of CSV files (--output-format=csv --output-folder=csvfiles) Diagram output depends on the installation of pygraphviz ("pip install pygraphviz") Full documentation here: * https://snowfakery.readthedocs.io/en/docs/ """ output_files = list(output_files) if output_files else [] stopping_criteria = stopping_criteria_from_target_number(target_number) output_format = output_format.lower() if output_format else None validate_options( yaml_file, option, dburls, mapping_file, debug_internals, generate_cci_mapping_file, output_format, output_files, output_folder, ) with configure_output_stream( dburls, mapping_file, output_format, output_files, output_folder ) as output_stream: try: with click.open_file(yaml_file) as f: summary = generate( open_yaml_file=f, user_options=dict(option), output_stream=output_stream, stopping_criteria=stopping_criteria, generate_continuation_file=generate_continuation_file, continuation_file=continuation_file, ) if debug_internals: debuginfo = yaml.dump( summary.summarize_for_debugging(), sort_keys=False ) sys.stderr.write(debuginfo) if generate_cci_mapping_file: with click.open_file(generate_cci_mapping_file, "w") as f: yaml.safe_dump( mapping_from_recipe_templates(summary), f, sort_keys=False ) except DataGenError as e: if debug_internals: raise e else: click.echo("") click.echo(e.prefix) raise click.ClickException(str(e)) from e
def generate_data( yaml_file: FileLike, *, parent_application: SnowfakeryApplication = None, # the parent application user_options: T.Dict[str, str] = None, # same as --option dburl: str = None, # same as --dburl dburls=[], # same as multiple --dburl options target_number: T.Tuple = None, # same as --target-number debug_internals: bool = None, # same as --debug-internals generate_cci_mapping_file: FileLike = None, # same as --generate-cci-mapping-file output_format: str = None, # same as --output-format output_file: FileLike = None, # same as --output-file output_files: T. List[FileLike] = None, # same as multiple --output-file options output_folder: FileLike = None, # same as --output-folder continuation_file: FileLike = None, # continuation file from last execution generate_continuation_file: FileLike = None, # place to generate continuation file should_create_cci_record_type_tables: bool = False, # create CCI Record type tables? load_declarations: T. Sequence[FileLike] = None, # read these load declarations for CCI ) -> None: stopping_criteria = stopping_criteria_from_target_number(target_number) dburls = dburls or ([dburl] if dburl else []) output_files = output_files or [] if output_file: output_files = output_files + [output_file] with ExitStack() as exit_stack: def open_with_cleanup(file, mode): return exit_stack.enter_context(open_file_like(file, mode)) parent_application = parent_application or SnowfakeryApplication( stopping_criteria) output_stream = exit_stack.enter_context( configure_output_stream(dburls, output_format, output_files, output_folder, parent_application)) yaml_path, open_yaml_file = open_with_cleanup(yaml_file, "r") _, open_new_continue_file = open_with_cleanup( generate_continuation_file, "w") _, open_continuation_file = open_with_cleanup(continuation_file, "r") _, open_cci_mapping_file = open_with_cleanup(generate_cci_mapping_file, "w") summary = generate( open_yaml_file=open_yaml_file, user_options=user_options, output_stream=output_stream, parent_application=parent_application, generate_continuation_file=open_new_continue_file, continuation_file=open_continuation_file, stopping_criteria=stopping_criteria, ) # This feature seems seldom useful. Delete it if it isn't missed # by fall 2021: # if debug_internals: # debuginfo = yaml.dump(summary.summarize_for_debugging(), sort_keys=False) # sys.stderr.write(debuginfo) if open_cci_mapping_file: declarations = gather_declarations(yaml_path or "", load_declarations) yaml.safe_dump( mapping_from_recipe_templates(summary, declarations), open_cci_mapping_file, sort_keys=False, ) if should_create_cci_record_type_tables: create_cci_record_type_tables(dburls[0])