DuckDB中.sql()与.execute()函数的区别是什么?
DuckDB Python API:execute() 和 sql() 的差异
核心差异点
返回值与使用方式
execute():执行后返回游标对象,必须手动调用fetchall()、fetchone()这类方法才能拿到查询结果。适合执行无返回的SQL(比如建表、插入数据),或者需要分步处理结果的场景。
示例:import duckdb conn = duckdb.connect() # 执行查询并获取结果 cursor = conn.execute("SELECT * FROM range(5)") results = cursor.fetchall() # 执行插入,获取受影响行数 insert_cursor = conn.execute("INSERT INTO test VALUES (1), (2)") print(insert_cursor.rowcount) # 输出2sql():执行后直接返回Relation对象,这是一个可迭代的结果集,能直接用.show()快速打印结果,或者.df()转成Pandas DataFrame,还能链式调用过滤、聚合等操作。更适合交互式查询或者需要对结果做后续数据处理的场景。
示例:import duckdb conn = duckdb.connect() # 直接获取结果集并查看 rel = conn.sql("SELECT * FROM range(5)") rel.show() # 链式操作 filtered_rel = rel.filter("value > 2") filtered_rel.df()
参数化与SQL注入防护
execute():原生支持参数化查询,用?作为占位符传递变量,能有效避免SQL注入,适合动态生成SQL的场景。
示例:limit = 10 conn.execute("SELECT * FROM range(?)", [limit])sql():如果要传入变量,通常会用Python的f-string,但这样存在SQL注入风险。不过它支持DuckDB的Relation链式操作,很多时候不需要拼接SQL就能完成复杂查询。
无返回语句的处理
两者都能执行DDL(建表、改表)、DML(插入、删除)这类无返回结果的SQL,但execute()可以通过游标对象的rowcount属性拿到受影响的行数,而sql()执行这类语句后返回的Relation对象没有有效数据,一般不需要额外处理。
内容的提问来源于stack exchange,提问作者Andrea Armani
相关产品推荐
相关产品推荐

