1

我使用 psycopg2 连接到 postgres 数据库。更准确地说,它是 Denodo 平台上的模式。

当我尝试使用公用表表达式进行数据库查询并使用命名占位符时,我收到以下错误:

DatabaseError: Execution failed on sql 'WITH table as (
SELECT INH_PAR_TECH_ID 
FROM tgesges 
WHERE PLNK_ID in %(PLNK)s
) 
SELECT * FROM table': Syntax error: Exception parsing query near '''
DETAIL: java.sql.SQLException: Syntax error: Exception parsing query near '''

导致此错误的查询如下所示:

PLNK = ('0000130433', '0000130434', '0000130296', '0000130292', '0000130293')

params = {'PLNK':PLNK}

query ="""WITH table as (
SELECT INH_PAR_TECH_ID 
FROM tgesges 
WHERE PLNK_ID in %(PLNK)s
) 
SELECT * FROM table""

conn = psycopg2.connect(user = user, password = password, host = hostname, port = port, dbname = schema)
df = pd.read_sql(sql=query, con=conn, params=params, parse_dates=parse_dates)
conn.close()

如果我在没有公用表表达式的情况下进行查询,则查询工作正常:

query = """
SELECT INH_PAR_TECH_ID as ID                   
FROM tgesges          
WHERE PLNK_ID in %(PLNK)s
"""

conn = psycopg2.connect(user = user, password = password, host = hostname, port = port, dbname = schema)
df = pd.read_sql(sql=query, con=conn, params=params, parse_dates=parse_dates)
conn.close()

即使我将查询作为公用表表达式并且不使用命名占位符,查询也可以正常工作:

query = """WITH table as (
SELECT INH_PAR_TECH_ID 
FROM tgesges 
WHERE PLNK_ID in ('0000130433', '0000130434', '0000130296', '0000130292', '0000130293')
) 
SELECT * FROM table""

conn = psycopg2.connect(user = user, password = password, host = hostname, port = port, dbname = schema)
df = pd.read_sql(sql=query, con=conn, params=params, parse_dates=parse_dates)
conn.close()

有谁知道我如何将 WITH 语句与命名占位符一起使用?

谢谢你的帮助!

与此同时,我发现该表是一个保留字。但即使我更改表的名称,它也不起作用。这是我使用 mogrify 时查询的输出:

你知道我必须改变什么来摆脱占位符中的字母“E”吗?

代码


PLNK = ("0000130433", "0000130434", "0000130296", "0000130292", "0000130293")
params = {'PLNK':PLNK}

query = """\
  
WITH grundselektion (INH_PAR_TECH_ID, d_min_eroe_sp3, d_start_ru) AS
(
SELECT      INH_PAR_TECH_ID                       
        ,   min(EROE_DT)
        ,   min(EROE_DT) + Interval '-1' YEAR     
FROM        tgesges         
WHERE       PLNK_ID in %(PLNK)s
AND         mutcd     ne 'D'
AND         MANDCD    = '001'
AND         PLNK_ID in %(PLNK)s
GROUP BY    INH_PAR_TECH_ID
)
 
SELECT    *
FROM      grundselektion AS gsel
"""
 
conn = psycopg2.connect(user = user, password = password, host = hostname, port = port, dbname = schema)
cur = conn.cursor()
print(cur.mogrify(query, params).decode('utf-8'))
cur.execute(query, params)
print(cur.fetchall())

出去

WITH grundselektion (INH_PAR_TECH_ID, d_min_eroe_sp3, d_start_ru) AS
(
SELECT      INH_PAR_TECH_ID                        
        ,   min(EROE_DT)
        ,   min(EROE_DT) + Interval '-1' YEAR      
FROM        tgesges          
WHERE       PLNK_ID in (E'0000130433', E'0000130434', E'0000130296', E'0000130292', E'0000130293')
AND         mutcd     ne 'D'
AND         MANDCD    = '001'
AND         PLNK_ID in (E'0000130433', E'0000130434', E'0000130296', E'0000130292', E'0000130293') 
GROUP BY    INH_PAR_TECH_ID
)

SELECT    *
FROM      grundselektion AS gsel

非常感谢和最好的问候汤姆

4

1 回答 1

0

table保留字,只需重命名您的变量。with除此之外,您可以照常使用语句:

# PLNK = ('0000130433', '0000130434', '0000130296', '0000130292', '0000130293')
PLNK = (1,5,999,1307)
params = {'PLNK':PLNK}

query ="""WITH foo as (
SELECT * 
FROM accounts 
WHERE id in %(PLNK)s
)
SELECT id FROM foo"""

print(cur.mogrify(query, params).decode('utf-8'))
cur.execute(query, params)
print(cur.fetchall())

出去:

WITH foo as (
SELECT * 
FROM accounts 
WHERE id in (1, 5, 999, 1307)
)
SELECT id FROM foo
[(999,), (1307,)]
于 2020-09-29T13:48:48.463 回答