@@ -224,7 +224,7 @@ async def get_dataset_columns(dataset_name: str):
224224@app .get ("/datasets/{dataset_name}/rows" )
225225async def get_dataset_rows (
226226 dataset_name : str ,
227- limit : int = Query (default = 50 , le = MAX_LIMIT ),
227+ limit : int = Query (default = 50 , ge = 1 , le = MAX_LIMIT ),
228228 offset : int = Query (default = 0 , ge = 0 ),
229229 columns : Optional [str ] = Query (default = None )
230230):
@@ -294,60 +294,35 @@ async def get_dataset_rows(
294294 logger .info (f"Returned schema info for corrupted { dataset_name } dataset" )
295295
296296 else :
297- # For other datasets, try normal reading
298- logger .info (f"Attempting to read { dataset_name } using to_arrow().to_pylist() approach" )
299-
300- # This is the approach that works in the search API
301- data_list = table .to_arrow ().to_pylist ()
302- total_count = len (data_list )
303-
304- # Apply pagination at the list level
305- start_idx = offset
306- end_idx = min (offset + limit , total_count )
307- paginated_data = data_list [start_idx :end_idx ]
308-
309- # Convert back to Arrow table for consistent processing
310- if paginated_data :
311- # Get the schema from the original table
312- schema = table .schema
297+ try :
298+ # Native pagination: read only the requested rows from disk
299+ total_count = table .count_rows ()
300+ end = min (offset + limit , total_count )
301+ if offset >= total_count :
302+ result_table = pa .table ({field .name : pa .array ([], type = field .type ) for field in table .schema })
303+ else :
304+ offsets = list (range (offset , end ))
305+ builder = table .take_offsets (offsets )
306+ if column_list :
307+ available_columns = [col for col in column_list if col in [field .name for field in table .schema ]]
308+ if available_columns :
309+ builder = builder .select (available_columns )
310+ result_table = builder .to_arrow ()
311+
312+ logger .info (f"Read { result_table .num_rows } rows (offset={ offset } , limit={ limit } ) from { dataset_name } ({ total_count } total)" )
313+
314+ except (AttributeError , TypeError ):
315+ # Fallback for older Lance versions without take_offsets/count_rows
316+ logger .info (f"Native pagination unavailable, using Arrow slice for { dataset_name } " )
317+ arrow_table = table .to_arrow ()
318+ total_count = arrow_table .num_rows
313319
314- # Apply column selection if specified
315- if column_list :
316- # Filter the schema and data
317- available_columns = [col for col in column_list if col in [field .name for field in schema ]]
318- if available_columns :
319- # Create filtered data
320- filtered_data = []
321- for row in paginated_data :
322- filtered_row = {col : row .get (col ) for col in available_columns }
323- filtered_data .append (filtered_row )
324- paginated_data = filtered_data
325-
326- # Create filtered schema
327- filtered_fields = [field for field in schema if field .name in available_columns ]
328- schema = pa .schema (filtered_fields )
329-
330- # Convert the paginated data back to Arrow format
331- arrays = []
332- for field in schema :
333- column_data = [row .get (field .name ) for row in paginated_data ]
334- arrays .append (pa .array (column_data , type = field .type ))
335-
336- result_table = pa .Table .from_arrays (arrays , schema = schema )
337- else :
338- # Empty result - create empty table with correct schema
339- schema = table .schema
340320 if column_list :
341- available_columns = [col for col in column_list if col in [ field . name for field in schema ] ]
321+ available_columns = [col for col in column_list if col in arrow_table . column_names ]
342322 if available_columns :
343- filtered_fields = [field for field in schema if field .name in available_columns ]
344- schema = pa .schema (filtered_fields )
345-
346- # Create empty arrays for each field
347- arrays = [pa .array ([], type = field .type ) for field in schema ]
348- result_table = pa .Table .from_arrays (arrays , schema = schema )
323+ arrow_table = arrow_table .select (available_columns )
349324
350- logger . info ( f"Successfully read { len ( paginated_data ) } rows from { dataset_name } " )
325+ result_table = arrow_table . slice ( offset , limit )
351326
352327 except Exception as general_error :
353328 logger .error (f"Reading failed for { dataset_name } : { general_error } " )
0 commit comments