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)
stdout
[SQLite] Type mismatch in column 0: expected INT64 but got STRING/BINARY
val: string