如何克服" OperationalError:太多的SQL变量"

时间:2018-03-09 04:16:40

标签: python python-3.x sqlite

我正在尝试将大小为(8760, 1574)的数据框插入SQLite的表格中。我的代码如下:

class DatabaseWorker(object):
    def __init__(self, db_name):
        self.db = db_name

    def create_table(self, table_name, column_names):
        conn = sqlite3.connect(self.db)
        cur = conn.cursor()
        q1 = 'DROP TABLE IF EXISTS %s' %(table_name)
        q2 = 'CREATE TABLE ' + table_name + ' ' + '(' + ', '.join(str(x) for x in column_names) + ')'
        cur.execute(q1)
        cur.execute(q2)
        conn.commit()
        conn.close()

    def insert_table(self, table_name, data):
        conn = sqlite3.connect(self.db)
        data.to_sql(table_name, conn, if_exists='append', index=False)
        conn.commit()
        conn.close()

cnx = DatabaseWorker("users")
cnx.create_table("user_activity", df_final.columns.values.tolist())
cnx.create_table("user_similarity_matrix", df_transformed.columns.values.tolist())
cnx.insert_table("user_activity", df_final)
cnx.insert_table("user_similarity_matrix", df_transformed)

df_final的尺寸为(249238, 7)df_transformed的尺寸为(8760, 1574)。插入df_final时没有错误,但插入df_transformed时出错。错误如下:

  

----> 5 cnx.insert_table(" user_similarity_matrix",df_transformed)

     

---> 30 data.to_sql(table_name,conn,if_exists ='追加',index = False)

     

pandas_sql.to_sql(frame,name,if_exists = if_exists,index = index,                         index_label = index_label,schema = schema,                         chunksize = chunksize,dtype = dtype)

     

OperationalError:SQL变量太多

"Too many SQL variables" error in django witih sqlite3的答案之一是999个变量的限制?有什么方法可以回避这个问题。我将非常感谢您的建议。非常感谢提前。

1 个答案:

答案 0 :(得分:1)

从 999 到 32766 的 SQLITE_MAX_VARIABLE_NUMBER was increased in SQLite > 3.32.0

<块引用>
  1. 单个 SQL 语句中的最大主机参数数

    [...]

    SQLite 分配空间来保存 1 和使用的最大主机参数号之间的所有主机参数。因此,包含像?1000000000 这样的主机参数的SQL 语句将需要千兆字节的存储空间。这很容易使主机的资源不堪重负。为防止内存分配过多,主机参数号的最大值为SQLITE_MAX_VARIABLE_NUMBER,3.32.0(2020-05-22)之前的SQLite版本默认为999,3.32.0之后的SQLite版本默认为32766。

这意味着具有 1574 列的 df_transformed 在最近的 SQLite 版本中应该也能正常工作。但是请注意,SQLITE_MAX_COLUMN=2000 和您没有太多空间来增加数据框中的列数。

<块引用>

SQLITE_MAX_COLUMN 的默认设置是 2000。您可以在编译时将其更改为大至 32767 的值。另一方面,许多有经验的数据库设计人员会争辩说,规范化良好的数据库永远不需要超过 100 列一张桌子。

在大多数应用程序中,列的数量很少 - 几十个。 SQLite 代码生成器中有些地方使用 O(N²) 算法,其中 N 是列数。

替代方案可以是在 SQLite TEXT 列、pandas.DataFrame sqlite3 pandas.DataFrame.to_json 等中使用 pandas.read_json / adapter 的自定义文档序列化.由于 SQLITE_MAX_LENGTH 是每行 1GB,序列化提供了更广泛的数据帧。