值语句中的 case

tan*_*ard 5 postgresql

我想将数据从 mysql 插入到 postgresql 中的表中。我想为特定的 id 执行 WHERE NOT EXISTS 语句。

   # Source data: MySQL
   curr_msql.execute(''' SELECT code, subjectname 
                          FROM test_subj ''')

    # Target data: PostgreSQL
    for row in curr_msql:
            curr_psql.execute(''' INSERT INTO subs (
                                                    created, modified,
                                                    subjcode, subjname,
                                                    is_pe_or_nstp)

                                  VALUES (current_timestamp, current_timestamp,
                                          %s, %s,
                                          %s) ''', (row['code'], row['subjectname'],
False))
Run Code Online (Sandbox Code Playgroud)

我想知道如何将“False”替换为 case 语句。就像是

CASE
    WHEN code like '%PE%' or code like '%NSTP%'
    THEN True
    ELSE False
END
Run Code Online (Sandbox Code Playgroud)

我尝试运行此代码:

for row in curr_msql:
            curr_psql.execute(''' INSERT INTO subs (
                                                    created, modified,
                                                    subjcode, subjname,
                                                    is_pe_or_nstp)

                                  VALUES (current_timestamp, current_timestamp,
                                          %s, %s,
                                          CASE
        WHEN code like '%PE%' or code like '%NSTP%'
        THEN True
        ELSE False
    END) ''', (row['code'], row['subjectname']))
Run Code Online (Sandbox Code Playgroud)

我收到IndexError: tuple out of index错误消息有什么建议吗?

  • 目标数据库是 PostgreSQL,源数据来自 MySQL。

dez*_*zso 5

您的问题的一部分是execute()试图将LIKE表达式 ( '%PE%')解释为占位符。您必须将所有百分号加倍,以便纯 SQL 中的以下查询(带有伪代码占位符)

SELECT ? WHERE 'abc' LIKE '%bc'
Run Code Online (Sandbox Code Playgroud)

变成

cur.execute("SELECT %s WHERE 'abc' LIKE '%%bc'", ['%s'])
cur.fetchall()
==> [('%s',)]
Run Code Online (Sandbox Code Playgroud)

由于该列code也来自源表,因此也需要从参数“馈送”。

for row in curr_msql:
    curr_psql.execute(''' 
        INSERT INTO subs (
                           created, modified,
                           subjcode, subjname,
                           is_pe_or_nstp )
        VALUES (current_timestamp, current_timestamp,
                %s, %s,
                CASE
                    WHEN %s LIKE %s OR %s LIKE %s
                    THEN TRUE
                    ELSE FALSE
                END) 
    ''', (row['code'], row['subjectname'], 
          row['code'], '%PE%', 
          row['code'], '%NSTP%'))
Run Code Online (Sandbox Code Playgroud)

并且更干净,使用命名参数:

for row in curr_msql:
    param = dict(code = row['code'], 
                 subjectname = row['subjectname'], 
                 str1 = '%PE%', 
                 str2 = '%NSTP%')
    curr_psql.execute(''' 
        INSERT INTO subs (
                           created, modified,
                           subjcode, subjname,
                           is_pe_or_nstp )
        VALUES (current_timestamp, current_timestamp,
                %(code)s, %(subjectname)s,
                CASE
                    WHEN %(code)s LIKE %(str1)s OR %(code)s LIKE %(str2)s
                    THEN TRUE
                    ELSE FALSE
                END) 
    ''', param)
Run Code Online (Sandbox Code Playgroud)

链接到 psycopg2:用于进一步阅读的基本模块用法