【问题标题】:Multiple insertion of one value in sqlalchemy statement to pandas将sqlalchemy语句中的一个值多次插入到pandas
【发布时间】:2016-08-11 04:12:22
【问题描述】:

我构建了一个 sql 子句,在其中引用了与 ab 相同的表,以将两个几何图形作为 postgis 命令进行比较。

我想使用 %s 运算符将值传递到 sql 语句中,并使用 to_sql, params kwargs 将结果读入 pandas 数据帧。目前我的代码将允许将一个值传递给一个%s,但我正在寻找同一值列表的多个插入。

我正在使用 psycopg2 连接到 postgresql 数据库。

下面是简化代码

sql = """
SELECT
    st_distance(a.the_geom, b.the_geom, true) AS dist
    FROM
        (SELECT
           table.*
           FROM table
           WHERE id in %s) AS a,

        (SELECT
           table.*
           FROM table
           WHERE id in %s) AS b
WHERE a.nid <> b.nid """

sampList = (14070,11184)
df = pd.read_sql(sql, con=conn, params = [sampList])

基本上,我希望在两个地方都用 sampList 值替换 %s。编写的代码将仅替换指示': list index out of range 的第一个值。如果我调整为拥有一个 %s 并用数字替换第二个 in 语句,代码运行,但最终我想重复这些值。

【问题讨论】:

  • 你必须传入参数占位符列表。
  • 您希望两个%s 参数引用相同的值列表吗?
  • @wildplasser,是的,这两个 %s 参数指的是同一个列表
  • 您不需要子查询,只需一个普通(反)连接即可。顺便说一句:您的问题是将列表传递给准备好的语句。使用两次只是一个细节。

标签: python sql postgresql pandas sqlalchemy


【解决方案1】:
  • 您不需要子查询,只需将表与自身连接即可:

    SELECT a.*, b.* -- or whatwever , st_distance(a.the_geom, b.the_geom, true) AS dist FROM ztable a JOIN ztable b ON a.nid < b.nid WHERE a.id IN (%s) AND b.id IN (%s) ;

  • 使用 CTE 避免重复(这可能不是最佳的,性能方面)

    WITH zt AS ( SELECT * FROM ztable WHERE id IN (%s) ) SELECT a.*, b.* -- or whatever , st_distance(a.the_geom, b.the_geom, true) AS dist FROM zt a JOIN zt b ON a.nid < b.nid ;

  • 就性能而言,我会坚持使用第一个版本,并提供两次列表参数。 (或使用 FORMAT() 构造引用它两次)

【讨论】:

    【解决方案2】:

    首先,我建议您使用updated SQL from @wildplasser - 这是一种更好、更有效的方法。

    现在您可以执行以下操作:

    sql_ = """\
    WITH zt AS (
            SELECT * FROM ztable
            WHERE id IN ({})
            )
    SELECT a.*, b.* -- or whatever
            , st_distance(a.the_geom, b.the_geom, true) AS dist
            FROM zt a
            JOIN zt b ON a.nid < b.nid 
    """
    sampList = (14070,11184)
    
    sql = sql_.format(','.join(['?' for x in sampList]))
    
    df = pd.read_sql(sql, con=conn, params=sampList)
    

    带参数动态生成的 SQL(AKA:准备好的语句、绑定变量等):

    In [27]: print(sql)
    WITH zt AS (
            SELECT * FROM ztable
            WHERE id IN (?,?)
            )
    SELECT a.*, b.* -- or whatever
            , st_distance(a.the_geom, b.the_geom, true) AS dist
            FROM zt a
            JOIN zt b ON a.nid < b.nid
    

    【讨论】:

    • 可能是一个不错的补充。 (抱歉,我对 ORM 一无所知,因为它们让我和其他人感到困惑;-)
    • @wildplasser,我希望你不介意我借用了你的 SQL(我已经为此说了“谢谢”);)
    • 不,一点也不。我喜欢协作!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 2016-05-29
    相关资源
    最近更新 更多