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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions