【问题标题】:How to execute an external program as part of an SQL query?如何在 SQL 查询中执行外部程序?
【发布时间】:2017-11-07 20:09:40
【问题描述】:

我试图弄清楚如何在 SQL 查询中嵌入对外部程序的调用。这个想法是,当 SQL 查询执行时,它将能够调用外部程序,传递来自数据库的记录,并接收可由该 SQL 查询使用的输出。

我想这样做并且我不能考虑替代方法的原因是,我的任务是使用 SQLite 和 SQLAlchemy 库在 Python 中手动重新创建一些数据库基准(特别是这些基准:https://amplab.cs.berkeley.edu/benchmark/ )。

其中描述的一个 SQL 查询(查询 4)以以下 SQL 语句开头:

CREATE TABLE url_counts_partial AS 
  SELECT TRANSFORM (line)
    USING "python /root/url_count.py" as (sourcePage, destPage, cnt) 
  FROM documents;

这是他们对查询 4 ​​的描述:

此查询调用外部 Python 函数,该函数从网络爬网数据集中提取和聚合 URL 信息。然后它会汇总每个 URL 的总计数。

表格“documents”包含一个名为“line”的列,它代表 HTML 的各个行。 “url_count.py”程序只是从 sys.stdin 解析行并打印制表符分隔的信息行(您可以在此处查看 url_count.py:https://github.com/amplab/benchmark/blob/master/runner/udf/url_count.py)。

我尝试运行以下命令:

from sqlalchemy import create_engine
engine = create_engine('sqlite:///myDatabase.db')

result = engine.execute("""SELECT TRANSFORM (line) 
             USING 'python /root/url_count.py' as (sourcePage, destPage, cnt)
             FROM documents"""")

但是,每次我尝试运行它时,我都会收到一个异常,并在底部抱怨语法错误:

sqlalchemy.exc.OperationalError: (OperationalError) near "USING": syntax error

我已经尝试以我能想到的各种方式调整语法。我尝试将 url_count.py 移动到本地目录。我已经尝试执行完整的语句(即添加回“CREATE TABLE url_counts_partial AS”)。我尝试过针对玩具数据库运行它的简化版本。我还尝试用对简单 bash 命令的调用替换对 python 程序的调用。似乎没有任何效果。我似乎也找不到关键字 TRANSFORM 或 USING 的任何在线文档。

我只是在某个地方犯了一个愚蠢的错误吗?或者,如果没有,是否有更简单/更正确的方法来执行此命令(同时仍然忠实于原始查询)?如果做不到这一点,即使只知道在哪里可以找到 TRANSFORM 或 USING 的手册页也会很有帮助。我对他们的任何其他查询都没有任何问题,所以我不知道为什么这个问题会变得如此令人头疼。

【问题讨论】:

  • 你需要转义你的单引号吗?为什么要尝试从 SQL 运行程序?这通常表明某处设计不当。
  • 一个好主意,但我尝试转义单引号,但没有帮助。我还尝试了转义和未转义的双引号,但无济于事。如果我理解正确,那么在 python 中的三引号之间都不需要转义,但可以肯定的是,我确实尝试了每一种排列。
  • 针对我尝试从 SQL 运行程序的原因:由于我的任务是忠实地重新创建现有基准,因此我必须遵循他们的设计。无论好坏,这就是他们所采用的设计,所以为了忠实于原始基准,我需要效仿。您可以在此处阅读有关我正在复制的基准的更多信息:amplab.cs.berkeley.edu/benchmark

标签: python sql database sqlite sqlalchemy


【解决方案1】:

SQLite 没有这样的 USING 子句来调用外部程序。

最近的机制是table-valued function,但Python sqlite3 模块没有公开它。

最简单的方法是手动执行该程序,并将其输出转换为 INSERT 命令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 2020-02-21
    • 2021-07-04
    • 1970-01-01
    相关资源
    最近更新 更多