Skip to content

SQLGraph.from_other fails with OperationalError #285

@yfukai

Description

@yfukai

The following example code fails with OperationalError: too many SQL variables. Maybe chunk insert resolves the issue?

src = "Data/aligned_labels_reseg_260402_tracked3.db"
dst = "Data/aligned_labels_reseg_260402_tracked3_verified.db"

# delete existing file — safe because this kernel has never opened it
Path(dst).unlink(missing_ok=True)

graph = td.graph.SQLGraph(drivername="sqlite", database=src)
subgraph = graph.filter(td.NodeAttr("verification_status") == 1).subgraph()

saved = td.graph.SQLGraph.from_other(subgraph, drivername="sqlite", database=dst)
# dispose engine immediately so the file lock is released on Windows
saved._engine.dispose()

print(f"Saved → {dst}")

Error:

---------------------------------------------------------------------------
OperationalError                          Traceback (most recent call last)
File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\base.py:1967, in Connection._exec_single_context(self, dialect, context, statement, parameters)
   1966     if not evt_handled:
-> 1967         self.dialect.do_execute(
   1968             cursor, str_statement, effective_parameters, context
   1969         )
   1971 if self._has_events or self.engine._has_events:

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\default.py:952, in DefaultDialect.do_execute(self, cursor, statement, parameters, context)
    951 def do_execute(self, cursor, statement, parameters, context=None):
--> 952     cursor.execute(statement, parameters)

OperationalError: too many SQL variables

The above exception was the direct cause of the following exception:

OperationalError                          Traceback (most recent call last)
Cell In[2], line 10
      6 
      7 graph = td.graph.SQLGraph(drivername="sqlite", database=src)
      8 subgraph = graph.filter(td.NodeAttr("verification_status") == 1).subgraph()
      9 
---> 10 saved = td.graph.SQLGraph.from_other(subgraph, drivername="sqlite", database=dst)
     11 # dispose engine immediately so the file lock is released on Windows
     12 saved._engine.dispose()
     13 

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\tracksdata\graph\_base_graph.py:1302, in BaseGraph.from_other(cls, other, **kwargs)
   1296 edge_attrs = edge_attrs.with_columns(
   1297     edge_attrs[col].map_elements(node_map.get, return_dtype=pl.Int64).alias(col)
   1298     for col in [DEFAULT_ATTR_KEYS.EDGE_SOURCE, DEFAULT_ATTR_KEYS.EDGE_TARGET]
   1299 )
   1300 graph.bulk_add_edges(list(edge_attrs.rows(named=True)))
-> 1302 if other.has_overlaps():
   1303     overlaps = other.overlaps()
   1304     overlaps = np.vectorize(node_map.get)(np.asarray(overlaps, dtype=int))

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\tracksdata\graph\_rustworkx_graph.py:743, in RustWorkXGraph.has_overlaps(self)
    734 def has_overlaps(self) -> bool:
    735     """
    736     Check if the graph has any overlaps.
    737 
   (...)    741         True if the graph has any overlaps, False otherwise.
    742     """
--> 743     return len(self.overlaps()) > 0

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\tracksdata\graph\_graph_view.py:236, in GraphView.overlaps(self, node_ids)
    234 if node_ids is None:
    235     node_ids = self.node_ids()
--> 236 return self._root.overlaps(node_ids)

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\tracksdata\graph\_sql_graph.py:1107, in SQLGraph.overlaps(self, node_ids)
   1101 if node_ids is not None:
   1102     query = query.filter(
   1103         self.Overlap.source_id.in_(node_ids),
   1104         self.Overlap.target_id.in_(node_ids),
   1105     )
-> 1107 return [[source_id, target_id] for source_id, target_id in query.all()]

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\orm\query.py:2711, in Query.all(self)
   2689 def all(self) -> List[_T]:
   2690     """Return the results represented by this :class:`_query.Query`
   2691     as a list.
   2692 
   (...)   2709         :meth:`_engine.Result.scalars` - v2 comparable method.
   2710     """
-> 2711     return self._iter().all()

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\orm\query.py:2864, in Query._iter(self)
   2861 params = self._params
   2863 statement = self._statement_20()
-> 2864 result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
   2865     statement,
   2866     params,
   2867     execution_options={"_sa_orm_load_options": self.load_options},
   2868 )
   2870 # legacy: automatically set scalars, unique
   2871 if result._attributes.get("is_single_entity", False):

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\orm\session.py:2351, in Session.execute(self, statement, params, execution_options, bind_arguments, _parent_execute_state, _add_event)
   2291 def execute(
   2292     self,
   2293     statement: Executable,
   (...)   2299     _add_event: Optional[Any] = None,
   2300 ) -> Result[Any]:
   2301     r"""Execute a SQL expression construct.
   2302 
   2303     Returns a :class:`_engine.Result` object representing
   (...)   2349 
   2350     """
-> 2351     return self._execute_internal(
   2352         statement,
   2353         params,
   2354         execution_options=execution_options,
   2355         bind_arguments=bind_arguments,
   2356         _parent_execute_state=_parent_execute_state,
   2357         _add_event=_add_event,
   2358     )

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\orm\session.py:2249, in Session._execute_internal(self, statement, params, execution_options, bind_arguments, _parent_execute_state, _add_event, _scalar_result)
   2244     return conn.scalar(
   2245         statement, params or {}, execution_options=execution_options
   2246     )
   2248 if compile_state_cls:
-> 2249     result: Result[Any] = compile_state_cls.orm_execute_statement(
   2250         self,
   2251         statement,
   2252         params or {},
   2253         execution_options,
   2254         bind_arguments,
   2255         conn,
   2256     )
   2257 else:
   2258     result = conn.execute(
   2259         statement, params or {}, execution_options=execution_options
   2260     )

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\orm\context.py:306, in AbstractORMCompileState.orm_execute_statement(cls, session, statement, params, execution_options, bind_arguments, conn)
    296 @classmethod
    297 def orm_execute_statement(
    298     cls,
   (...)    304     conn,
    305 ) -> Result:
--> 306     result = conn.execute(
    307         statement, params or {}, execution_options=execution_options
    308     )
    309     return cls.orm_setup_cursor_result(
    310         session,
    311         statement,
   (...)    315         result,
    316     )

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\base.py:1419, in Connection.execute(self, statement, parameters, execution_options)
   1417     raise exc.ObjectNotExecutableError(statement) from err
   1418 else:
-> 1419     return meth(
   1420         self,
   1421         distilled_parameters,
   1422         execution_options or NO_OPTIONS,
   1423     )

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\sql\elements.py:527, in ClauseElement._execute_on_connection(self, connection, distilled_params, execution_options)
    525     if TYPE_CHECKING:
    526         assert isinstance(self, Executable)
--> 527     return connection._execute_clauseelement(
    528         self, distilled_params, execution_options
    529     )
    530 else:
    531     raise exc.ObjectNotExecutableError(self)

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\base.py:1641, in Connection._execute_clauseelement(self, elem, distilled_parameters, execution_options)
   1629 compiled_cache: Optional[CompiledCacheType] = execution_options.get(
   1630     "compiled_cache", self.engine._compiled_cache
   1631 )
   1633 compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
   1634     dialect=dialect,
   1635     compiled_cache=compiled_cache,
   (...)   1639     linting=self.dialect.compiler_linting | compiler.WARN_LINTING,
   1640 )
-> 1641 ret = self._execute_context(
   1642     dialect,
   1643     dialect.execution_ctx_cls._init_compiled,
   1644     compiled_sql,
   1645     distilled_parameters,
   1646     execution_options,
   1647     compiled_sql,
   1648     distilled_parameters,
   1649     elem,
   1650     extracted_params,
   1651     cache_hit=cache_hit,
   1652 )
   1653 if has_events:
   1654     self.dispatch.after_execute(
   1655         self,
   1656         elem,
   (...)   1660         ret,
   1661     )

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\base.py:1846, in Connection._execute_context(self, dialect, constructor, statement, parameters, execution_options, *args, **kw)
   1844     return self._exec_insertmany_context(dialect, context)
   1845 else:
-> 1846     return self._exec_single_context(
   1847         dialect, context, statement, parameters
   1848     )

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\base.py:1986, in Connection._exec_single_context(self, dialect, context, statement, parameters)
   1983     result = context._setup_result_proxy()
   1985 except BaseException as e:
-> 1986     self._handle_dbapi_exception(
   1987         e, str_statement, effective_parameters, cursor, context
   1988     )
   1990 return result

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\base.py:2363, in Connection._handle_dbapi_exception(self, e, statement, parameters, cursor, context, is_sub_exec)
   2361 elif should_wrap:
   2362     assert sqlalchemy_exception is not None
-> 2363     raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
   2364 else:
   2365     assert exc_info[1] is not None

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\base.py:1967, in Connection._exec_single_context(self, dialect, context, statement, parameters)
   1965                 break
   1966     if not evt_handled:
-> 1967         self.dialect.do_execute(
   1968             cursor, str_statement, effective_parameters, context
   1969         )
   1971 if self._has_events or self.engine._has_events:
   1972     self.dispatch.after_cursor_execute(
   1973         self,
   1974         cursor,
   (...)   1978         context.executemany,
   1979     )

File c:\Users\sangw\Desktop\Label\.venv\Lib\site-packages\sqlalchemy\engine\default.py:952, in DefaultDialect.do_execute(self, cursor, statement, parameters, context)
    951 def do_execute(self, cursor, statement, parameters, context=None):
--> 952     cursor.execute(statement, parameters)

OperationalError: (sqlite3.OperationalError) too many SQL variables
[SQL: SELECT "Overlap".source_id AS "Overlap_source_id", "Overlap".target_id AS "Overlap_target_id" 
FROM "Overlap" 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions