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