@@ -1620,7 +1620,6 @@ def create_concurrent_cursor_from_perpartition_cursor(
16201620 stream_namespace = stream_namespace ,
16211621 config = config ,
16221622 message_repository = NoopMessageRepository (),
1623- stream_state_migrations = stream_state_migrations ,
16241623 )
16251624 )
16261625
@@ -1955,7 +1954,7 @@ def create_declarative_stream(
19551954 )
19561955 if combined_slicers and not isinstance (combined_slicers , Cursor ):
19571956 raise ValueError (
1958- "Unsupported Slicer is used. PerPartitionWithGlobalCursor should be used here instead"
1957+ "Unsupported Slicer is used. PerPartitionWithGlobalCursor should be used here instead" # FIXME update error message
19591958 )
19601959 cursor = (
19611960 combined_slicers
@@ -2090,15 +2089,15 @@ def create_declarative_stream(
20902089 options ["name" ] = model .name
20912090 schema_loader = DefaultSchemaLoader (config = config , parameters = options )
20922091
2093- if concurrent or (hasattr (model .retriever , "partition_router" ) and model .retriever .partition_router ):
2092+ if concurrent or (hasattr (model .retriever , "partition_router" ) and model .retriever .partition_router and model . incremental_sync ):
20942093 stream_name = model .name or ""
20952094 cursor = combined_slicers \
20962095 if combined_slicers and isinstance (combined_slicers , Cursor ) \
20972096 else FinalStateCursor (stream_name , None , self ._message_repository )
20982097 partition_generator = StreamSlicerPartitionGenerator (
20992098 DeclarativePartitionFactory (
21002099 stream_name ,
2101- schema_loader . get_json_schema () ,
2100+ schema_loader ,
21022101 retriever ,
21032102 self ._message_repository ,
21042103 ),
@@ -2107,12 +2106,13 @@ def create_declarative_stream(
21072106 return DefaultStream (
21082107 partition_generator = partition_generator ,
21092108 name = stream_name ,
2110- json_schema = schema_loader .get_json_schema (),
2109+ json_schema = lambda : schema_loader .get_json_schema (),
21112110 availability_strategy = AlwaysAvailableAvailabilityStrategy (), # FIXME it seems this is what we do in the ConcurrentDeclarativeSource but it feels wrong
21122111 primary_key = get_primary_key_from_stream (primary_key ),
21132112 cursor_field = cursor .cursor_field .cursor_field_key if hasattr (cursor , "cursor_field" ) else "" , # FIXME we should have the cursor field has part of the interface of cursor
21142113 logger = logging .getLogger (f"airbyte.{ stream_name } " ), # FIXME this is a breaking change compared to the old implementation,
21152114 cursor = cursor ,
2115+ supports_file_transfer = hasattr (model , "file_uploader" ) and bool (model .file_uploader )
21162116 )
21172117 return DeclarativeStream (
21182118 name = model .name or "" ,
@@ -2188,14 +2188,26 @@ def _build_incremental_cursor(
21882188 partition_router = stream_slicer ,
21892189 )
21902190 elif model .incremental_sync :
2191- return self .create_concurrent_cursor_from_datetime_based_cursor ( # type: ignore # This is a known issue that we are creating and returning a ConcurrentCursor which does not technically implement the (low-code) StreamSlicer. However, (low-code) StreamSlicer and ConcurrentCursor both implement StreamSlicer.stream_slices() which is the primary method needed for checkpointing
2192- model_type = DatetimeBasedCursorModel ,
2193- component_definition = model .incremental_sync .__dict__ ,
2194- stream_name = model .name or "" ,
2195- stream_namespace = None ,
2196- config = config or {},
2197- stream_state_migrations = model .state_migrations ,
2198- )
2191+ if type (model .incremental_sync ) == IncrementingCountCursorModel :
2192+ return self .create_concurrent_cursor_from_incrementing_count_cursor (
2193+ model_type = IncrementingCountCursorModel ,
2194+ component_definition = model .incremental_sync .__dict__ ,
2195+ stream_name = model .name or "" ,
2196+ stream_namespace = None ,
2197+ config = config or {},
2198+ stream_state_migrations = model .state_migrations ,
2199+ )
2200+ elif type (model .incremental_sync ) == DatetimeBasedCursorModel :
2201+ return self .create_concurrent_cursor_from_datetime_based_cursor ( # type: ignore # This is a known issue that we are creating and returning a ConcurrentCursor which does not technically implement the (low-code) StreamSlicer. However, (low-code) StreamSlicer and ConcurrentCursor both implement StreamSlicer.stream_slices() which is the primary method needed for checkpointing
2202+ model_type = type (model .incremental_sync ),
2203+ component_definition = model .incremental_sync .__dict__ ,
2204+ stream_name = model .name or "" ,
2205+ stream_namespace = None ,
2206+ config = config or {},
2207+ stream_state_migrations = model .state_migrations ,
2208+ )
2209+ else :
2210+ raise ValueError (f"Incremental sync of type { type (model .incremental_sync )} is not supported" )
21992211 return None
22002212
22012213 def _build_resumable_cursor (
@@ -3235,9 +3247,6 @@ def _get_url() -> str:
32353247 config = config ,
32363248 )
32373249
3238- # Define cursor only if per partition or common incremental support is needed
3239- cursor = stream_slicer if isinstance (stream_slicer , DeclarativeCursor ) else None
3240-
32413250 if (
32423251 not isinstance (stream_slicer , (ConcurrentCursor , ConcurrentPerPartitionCursor ))
32433252 or type (stream_slicer ) not in [ConcurrentCursor , ConcurrentPerPartitionCursor ]
@@ -3260,6 +3269,7 @@ def _get_url() -> str:
32603269 ),
32613270 )
32623271
3272+ cursor = stream_slicer if isinstance (stream_slicer , (ConcurrentCursor , DeclarativeCursor )) else None
32633273 cursor_used_for_stop_condition = cursor if stop_condition_on_cursor else None
32643274 paginator = (
32653275 self ._create_component_from_model (
@@ -3311,7 +3321,7 @@ def _get_url() -> str:
33113321 record_selector = record_selector ,
33123322 stream_slicer = stream_slicer ,
33133323 request_option_provider = request_options_provider ,
3314- cursor = cursor ,
3324+ cursor = None ,
33153325 config = config ,
33163326 ignore_stream_slicer_parameters_on_paginated_requests = ignore_stream_slicer_parameters_on_paginated_requests ,
33173327 parameters = model .parameters or {},
@@ -3325,7 +3335,7 @@ def _get_url() -> str:
33253335 record_selector = record_selector ,
33263336 stream_slicer = stream_slicer ,
33273337 request_option_provider = request_options_provider ,
3328- cursor = cursor ,
3338+ cursor = None ,
33293339 config = config ,
33303340 ignore_stream_slicer_parameters_on_paginated_requests = ignore_stream_slicer_parameters_on_paginated_requests ,
33313341 additional_query_properties = query_properties ,
@@ -3713,7 +3723,7 @@ def _create_message_repository_substream_wrapper(
37133723 self , model : ParentStreamConfigModel , config : Config , ** kwargs : Any
37143724 ) -> Any :
37153725 # getting the parent state
3716- child_state = self ._connector_state_manager .get_stream_state (kwargs ["stream_name" ], None )
3726+ child_state = self ._connector_state_manager .get_stream_state (kwargs ["stream_name" ], None ) # FIXME adding `stream_name` as a parameter means it will be a breaking change. I assume this is mostly called internally so I don't think we need to bother that much about this but still raising the flag
37173727 if model .incremental_dependency and child_state :
37183728 parent_stream_name = model .stream .name or ""
37193729 parent_state = ConcurrentPerPartitionCursor .get_parent_state (child_state , parent_stream_name )
@@ -4070,7 +4080,7 @@ def create_grouping_partition_router(
40704080 self , model : GroupingPartitionRouterModel , config : Config , ** kwargs : Any
40714081 ) -> GroupingPartitionRouter :
40724082 underlying_router = self ._create_component_from_model (
4073- model = model .underlying_partition_router , config = config
4083+ model = model .underlying_partition_router , config = config , ** kwargs ,
40744084 )
40754085 if model .group_size < 1 :
40764086 raise ValueError (f"Group size must be greater than 0, got { model .group_size } " )
0 commit comments