From cffb89002cb7a66b1cf70a42e2e396595ac35bb9 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Sun, 26 May 2019 05:27:29 +0200 Subject: [PATCH] fix ChannelDB.compare_channels: was raising "too many SQL variables" sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) too many SQL variables --- electrum/lnrouter.py | 16 +++++++++------- electrum/sql_db.py | 4 ++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/electrum/lnrouter.py b/electrum/lnrouter.py index 7cfe34f57..838e08ef7 100644 --- a/electrum/lnrouter.py +++ b/electrum/lnrouter.py @@ -40,10 +40,10 @@ from sqlalchemy import Column, ForeignKey, Integer, String, Boolean from sqlalchemy.orm.query import Query from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.sql import not_, or_ -from .sql_db import SqlDB, sql +from .sql_db import SqlDB, sql, SQLITE_LIMIT_VARIABLE_NUMBER from . import constants -from .util import bh2u, profiler, get_headers_dir, bfh, is_ip_address, list_enabled_bits, print_msg +from .util import bh2u, profiler, get_headers_dir, bfh, is_ip_address, list_enabled_bits, print_msg, chunks from .logging import Logger from .storage import JsonDB from .lnverifier import LNChannelVerifier, verify_sig_for_channel_update @@ -231,12 +231,14 @@ class ChannelDB(SqlDB): @profiler def compare_channels(self, channel_ids): ids = [x.hex() for x in channel_ids] + known = set() # I need to get the unknown, and also the channels that need refresh - known = self.DBSession \ - .query(ChannelInfo) \ - .filter(ChannelInfo.short_channel_id.in_(ids)) \ - .all() - known = [bfh(r.short_channel_id) for r in known] + for ids_chunk in chunks(ids, SQLITE_LIMIT_VARIABLE_NUMBER): + known_part = self.DBSession \ + .query(ChannelInfo) \ + .filter(ChannelInfo.short_channel_id.in_(ids_chunk)) \ + .all() + known |= set(bfh(r.short_channel_id) for r in known_part) return known @sql diff --git a/electrum/sql_db.py b/electrum/sql_db.py index 6dc3037d3..998f3f90c 100644 --- a/electrum/sql_db.py +++ b/electrum/sql_db.py @@ -10,6 +10,10 @@ from sqlalchemy.orm import sessionmaker from .logging import Logger +# https://stackoverflow.com/questions/26971050/sqlalchemy-sqlite-too-many-sql-variables +SQLITE_LIMIT_VARIABLE_NUMBER = 999 + + def sql(func): """wrapper for sql methods""" def wrapper(self, *args, **kwargs):