After looking at the dagster codebase for your error, which I found here. It confirmed what I read in the tutorial that "Output names must be unique".
Given that you are declaring Output in a for-loop and the error you have received, it's likely that your Output object name is not unique.
UPDATE:
From the outreach you made to dagster by opening an issue, I tested the idea of creating Outputs dynamically at run-time and it works fine if you define your dynamic code outside of a @solid
. I did find that when attempting to build my dynamic data within a @solid
with the intention of using its output as solid configuration input to a successor @solid
that the successor @solid
didn't pick up the updated structure. The result was me receiving an dagster.core.errors.DagsterInvariantViolationError
Below is my code to validate dynamic Output yielding at runtime when executing the dynamic-data generation outside of a solid. I'm guessing this might be a bit of an anti-pattern, but maybe not quite yet if Dagster isn't at the maturity level quite yet to handle the scenario you bring up. Also note that something I didn't handle is doing something with all of the yielded Output objects.
"""dagit -f dynamic_output_at_runtime.py -n dynamic_output_at_runtime"""
import random
from dagster import (
Output,
OutputDefinition,
execute_pipeline,
pipeline,
solid,
SystemComputeExecutionContext
)
# Create some dynamic OutputDefinition list for each execution
start = 1
stop = 100
limit = random.randint(1, 10)
random_set_of_ints = {random.randint(start, stop) for iter in range(limit)}
output_defs_runtime = [OutputDefinition(
name=f'output_{num}') for num in random_set_of_ints]
@solid(output_defs=output_defs_runtime)
def ints_for_all(context: SystemComputeExecutionContext):
for num in random_set_of_ints:
out_name = f"output_{num}"
context.log.info(f"output object name: {out_name}")
yield Output(num, out_name)
@pipeline
def dynamic_output_at_runtime():
x = ints_for_all()
print(x)
if __name__ == '__main__':
result = execute_pipeline(dynamic_output_at_runtime)
assert result.success
The result of me re-running this pipeline are different Output yields each time:
python dynamic_output_at_runtime.py
_ints_for_all_outputs(output_56=<dagster.core.definitions.composition.InvokedSolidOutputHandle object at 0x7fb899cea160>, output_8=<dagster.core.definitions.composition.InvokedSolidOutputHandle object at 0x7fb899cea198>, output_58=<dagster.core.definitions.composition.InvokedSolidOutputHandle object at 0x7fb899cea1d0>, output_35=<dagster.core.definitions.composition.InvokedSolidOutputHandle object at 0x7fb899cea208>)
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - PIPELINE_START - Started execution of pipeline "dynamic_output_at_runtime".
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - ENGINE_EVENT - Executing steps in process (pid: 9456)
event_specific_data = {"metadata_entries": [["pid", null, ["9456"]], ["step_keys", null, ["{'ints_for_all.compute'}"]]]}
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - STEP_START - Started execution of step "ints_for_all.compute".
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - INFO - system - a1273816-16b0-439b-ae32-dbd819f65b9a - output object name: output_56
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - STEP_OUTPUT - Yielded output "output_56" of type "Any". (Type check passed).
event_specific_data = {"intermediate_materialization": null, "step_output_handle": ["ints_for_all.compute", "output_56"], "type_check_data": [true, "output_56", null, []]}
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - INFO - system - a1273816-16b0-439b-ae32-dbd819f65b9a - output object name: output_8
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - STEP_OUTPUT - Yielded output "output_8" of type "Any". (Type check passed).
event_specific_data = {"intermediate_materialization": null, "step_output_handle": ["ints_for_all.compute", "output_8"], "type_check_data": [true, "output_8", null, []]}
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - INFO - system - a1273816-16b0-439b-ae32-dbd819f65b9a - output object name: output_58
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - STEP_OUTPUT - Yielded output "output_58" of type "Any". (Type check passed).
event_specific_data = {"intermediate_materialization": null, "step_output_handle": ["ints_for_all.compute", "output_58"], "type_check_data": [true, "output_58", null, []]}
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - INFO - system - a1273816-16b0-439b-ae32-dbd819f65b9a - output object name: output_35
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - STEP_OUTPUT - Yielded output "output_35" of type "Any". (Type check passed).
event_specific_data = {"intermediate_materialization": null, "step_output_handle": ["ints_for_all.compute", "output_35"], "type_check_data": [true, "output_35", null, []]}
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - STEP_SUCCESS - Finished execution of step "ints_for_all.compute" in 2.17ms.
event_specific_data = {"duration_ms": 2.166192003642209}
solid = "ints_for_all"
solid_definition = "ints_for_all"
step_key = "ints_for_all.compute"
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - ENGINE_EVENT - Finished steps in process (pid: 9456) in 3.11ms
event_specific_data = {"metadata_entries": [["pid", null, ["9456"]], ["step_keys", null, ["{'ints_for_all.compute'}"]]]}
2019-11-27 08:33:32 - dagster - DEBUG - dynamic_output_at_runtime - a1273816-16b0-439b-ae32-dbd819f65b9a - PIPELINE_SUCCESS - Finished execution of pipeline "dynamic_output_at_runtime".
I hope this helps!