【问题标题】:Python Script for SQL Server - Update values with MERGESQL Server 的 Python 脚本 - 使用 MERGE 更新值
【发布时间】:2018-07-27 16:27:49
【问题描述】:

我有这个插入 SQL 数据库的 python 函数。该脚本是这样的,每次重新运行时,除了新行之外,它还必须再次插入同一行。最终我会改变它,让它只插入新行,但现在我必须使用某种更新语句。

我知道我可以在 SQL Server 中使用 MERGE 来实现类似于 MySQL 的 ON DUPLICATE KEY UPDATE 的功能,但我不确定应该如何使用它。欢迎任何建议。谢谢!

def sqlInsrt(headers, values):
    #create string input of mylisth
    strheaders = ','.join(str(i) for i in headers)

    #create string ? param's for INSERT clause
    placestr = ','.join(i for i in ["?" for i in headers])

    #create string ? param's for UPDATE clause
    replacestr = ', '.join(['{}=?'.format(h) for h in headers])

    #Setup and execute SQL query 
    insert = ("INSERT INTO "+part+" ("+strheaders+") VALUES ("+placestr+")")
    cursor.execute(insert, values)
    cnx.commit()

【问题讨论】:

  • placestr = ",".join("?" for i in headers).
  • 传递给execute的语句是什么
  • 通过我的编辑,该语句只是一个 INSERT。 'part' 变量未在函数中定义,但它控制数据将插入到哪个表中。 'strheaders' 和 'placestr' 是要插入的值的标题和参数占位符
  • 这是一个等待发生的漏洞。您将列名直接包含在 SQL 中。有人会过来并将用户输入作为列名直接传递给这个函数。
  • 嗯,我是作为公司实习生写的,它只会在内部服务器上使用,整个应用程序处理的信息是公共信息。所有这些都可以在我从中清理数据的某个网站上找到。

标签: python sql sql-merge


【解决方案1】:

您应该阅读 docs 以了解合并。 基本上合并到 TargetTable 使用源表 ON TargetTable.id = SourceTable.id …… 然后,您可以阅读有关使用 When not marched by Target 等的文档。 所以你的 Python 可能会使用参数交换表名和连接

【讨论】:

    【解决方案2】:

    我编写了一个脚本来解决合并两个结构相同的表的最简单情况,其中一个包含新的/更新的数据。这在增量数据导入中很有用。您可以根据需要对其进行扩展(例如,如果您需要 2 型 SCD):

    def create_merge_query(
        stg_schema: str,
        stg_table: str,
        schema: str,
        table: str,
        primary_key: str,
        con: pyodbc.Connection,
    ) -> str:
        """
        Create a merge query for the simplest possible upsert scenario:
        - updating and inserting all fields
        - merging on a single column, which has the same name in both tables
    
        Args:
            stg_schema (str): The schema where the staging table is located.
            stg_table (str): The table with new/updated data.
            schema (str): The schema where the table is located.
            table (str): The table to merge into.
            primary_key (str): The column on which to merge.
        """
    
        columns_query = f"""
        SELECT 
            col.name
        FROM sys.tables AS tab
            INNER JOIN sys.columns AS col
                ON tab.object_id = col.object_id
        WHERE tab.name = '{table}'
        AND schema_name(tab.schema_id) = '{schema}'
        ORDER BY column_id;
        """
        columns_query_result = con.execute(columns_query)
        columns = [tup[0] for tup in columns_query_result]
        columns_stg_fqn = [f"stg.{col}" for col in columns]
        update_pairs = [f"existing.{col} = stg.{col}" for col in columns]
        merge_query = f"""
        MERGE INTO {schema}.{table} existing
            USING {stg_schema}.{stg_table} stg
            ON stg.{primary_key} = existing.{primary_key}
            WHEN MATCHED
                THEN UPDATE SET {", ".join(update_pairs)}
            WHEN NOT MATCHED
                THEN INSERT({", ".join(columns)})
                VALUES({", ".join(columns_stg_fqn)});
        """
        return merge_query
    

    【讨论】:

      猜你喜欢
      • 2011-01-29
      • 2018-03-11
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 2021-03-23
      相关资源
      最近更新 更多