SQLite 秘籍

更改结果集的批处理大小

秘籍来源:sqlite_batch_rows.py

ADBC SQLite 驱动程序允许控制结果集中批处理的大小。由于驱动程序执行类型推断,这也控制了驱动程序查看多少行以找出类型。如果您知道结果集前面有许多 NULL 行,您可以考虑增加批处理大小,以便驱动程序可以推断出正确的类型。

28import adbc_driver_sqlite.dbapi
29
30conn = adbc_driver_sqlite.dbapi.connect()

首先,我们将设置一个包含 1024 个 NULL 值的演示表。

34with conn.cursor() as cur:
35    cur.execute("CREATE TABLE demo (val TEXT)")
36
37    cur.execute(
38        """
39    WITH RECURSIVE series(n) AS (
40        SELECT 1
41        UNION ALL
42        SELECT n + 1
43        FROM series
44        WHERE n + 1 <= 1024
45    )
46    INSERT INTO demo (val)
47    SELECT NULL
48    FROM series
49    """
50    )
51
52    cur.execute("INSERT INTO demo VALUES ('foo'), ('bar'), ('baz')")

如果我们天真地查询该表,我们会得到一个错误,因为驱动程序首先查看前 1024 个值来确定列类型。但是由于每个值都是 NULL,它会回退到默认类型 int64,这在它遇到下一个批处理中的字符串时会造成问题。

59with conn.cursor() as cur:
60    try:
61        cur.execute("SELECT * FROM demo")
62        print(cur.fetchallarrow().schema)
63    except OSError as e:
64        print(e)
65        # Output:
66        # [SQLite] Type mismatch in column 0: expected INT64 but got STRING/BINARY
67    else:
68        raise RuntimeError("Expected an error")

我们可以告诉驱动程序增加批处理大小(从而查看更多行)。

73with conn.cursor() as cur:
74    cur.adbc_statement.set_options(
75        **{
76            adbc_driver_sqlite.StatementOptions.BATCH_ROWS.value: 2048,
77        }
78    )
79    cur.execute("SELECT * FROM demo")
80    print(cur.fetchallarrow().schema)
标准输出
[SQLite] Type mismatch in column 0: expected INT64 but got STRING/BINARY
val: string