【问题标题】:WHERE clause for different column names不同列名的 WHERE 子句
【发布时间】:2020-02-12 16:28:39
【问题描述】:

下面的脚本反映了我更新、编辑的尝试(遵循以下建议)使用操作数据库中的表中的行填充维度表,前提是 PANDAS DataFrame 的主键是通过连接 OPDB 中相关表的 ID 列创建的,维度表中不存在。

import mysql.connector
import pandas as pd

        ...

op_cursor = op_connector.cursor
dwh_cursor = dwh_connector.cursor

        ...

class dimension_table:  
def __init__(self, dwh_cols, op_cols, dim_id, dwh_table_name, op_table_name,op_args=None, dwh_args=None):
    self.dwh_cols = ('')
    self.op_cols = ('')
    self.dim_id = dim_id
    self.dwh_table_name = dwh_table_name
    self.op_table_name = '`*opdb.*`.' + op_table_name
    self.op_args = ",".join(op_cols)
    self.dwh_args = ",".join(dwh_cols)

        ...


billing_address_data = dimension_table(("id","address", "alias", "postal_code", "type", "city", "country", 
                                       "geolocation"),
                                      ("id","address", "alias", "postal_code", "type", "city", "country", 
                                       "geolocation"),
                                      billing_address_dim_id,'billing_address_dim', 'billing_address')

        ...

def load_dim(instance):
sql = """INSERT INTO {dwh} ({dwh_cols})
         SELECT {op_cols} 
         FROM {op}
         WHERE {pk} NOT IN
            (SELECT {pk} FROM {dwh} WHERE id = %s)
         LIMIT 1
      """
for key in instance.dim_id:

    try:            
        # ID APPEND
        dwh_cursor.execute(sql.format(dwh = instance.dwh_table_name,
                                      dwh_cols = instance.dwh_args,
                                      op_cols = instance.op_args,
                                      op = instance.op_table_name,
                                      pk = 'id'),

                           str(key))

        dwh_connector.commit()

    except mysql.connector.ProgrammingError as err:                         
        # ORDER_ID APPEND
        dwh_cursor.execute(sql.format(dwh = instance.dwh_table_name,
                                      dwh_cols = instance.dwh_args,
                                      op_cols = instance.op_args,
                                      op = instance.op_table_name,
                                      pk = 'order_id'),

                           str(key))

        dwh_connector.commit()

    billing_profile_op_id = dwh_cursor.lastrowid 

      ...

load_dim(order_items_data)

我的最新问题是由于在脚本中运行最后一行代码导致的错误,load_dim(order_items_data)。 它是带有 order_id PK 的 order_items 表。

ProgrammingError: 1054 (42S22): 'where 子句'中的未知列 'id'

【问题讨论】:

  • 请在您的问题中添加minimal reproducible example,以及遇到的具体错误。
  • 请为有问题的 SQL 表添加示例数据。还包括您当前的 Python 代码。
  • 你试过WHERE id = '"+str(key)+"' OR order_id = '"+str(key)+"'吗?
  • 请添加表结构或一些示例数据。如果没有有关架构或数据的信息,很难猜测。
  • @LeoGer 。 . .只是您问这表明您的数据模型存在问题。您应该将它们存储在单独的中,而不是将重复值存储在单独的列中。

标签: python mysql etl


【解决方案1】:

考虑try/except 并通过使用一个带有IN 子句的纯insert-select SQL 查询来避免所有查询构建和fetch 检查,因为这反映了非重复追加查询的需要。见NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL

下面使用LIMIT 1 替换fetchone(),否则使用TOP 1fetch first 1 rows only,具体取决于RDBMS。此外,参数占位符使用%s,否则使用?,具体取决于Python DB-API。在以后的帖子中,始终标记 RDBMS 并使用 import 行显示 DB-API。

def load_dim(instance):
    sql = """INSERT INTO {dwh} ({dwh_cols})
             SELECT {op_cols} 
             FROM {op}
             WHERE {pk} NOT IN
                (SELECT {pk} FROM {dwh} WHERE {pk} = %s)
             LIMIT 1
          """
    for key in instance.dim_id:

        try:            
            # ID APPEND
            dwh_cursor.execute(sql.format(dwh = instance.dwh_table_name,
                                          dwh_cols = instance.dwh_args,
                                          op_cols = instance.op_args,
                                          op = instance.op_table_name,
                                          pk = 'id'),
                               (str(key),))

            dwh_connector.commit()

        except Exception as e:                          # ADJUST TO DB-API SPECIFIC Error
            # ORDER_ID APPEND
            dwh_cursor.execute(sql.format(dwh = instance.dwh_table_name,
                                          dwh_cols = instance.dwh_args,
                                          op_cols = instance.op_args,
                                          op = instance.op_table_name,
                                          pk = 'order_id'),
                               (str(key),))

            dwh_connector.commit()

        billing_profile_op_id = dwh_cursor.lastrowid    # RETURNS 0 IF NO DATA APPENDED

【讨论】:

  • 感谢您的回答!我还没到那里,所以已经相应地编辑了我的问题。
  • 我的错误。对于cursor.execute 中的参数参数,将str(key) 作为元组或列表(非标量)传递:(str(key),)[str(key)]。查看我的编辑。
  • 感谢您的编辑,它解决了我手头的问题,但是不幸的是,它在我的脚本中发现了另一个错误,如我编辑的问题中所述。
  • 在SQL字符串中,将WHERE id = %s改为WHERE {pk} = %s
  • 太棒了!很高兴听到并乐于提供帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多