SQL executemany() 与 python 和一个数组和 ON DUPLICATE KEY

Posted

技术标签:

【中文标题】SQL executemany() 与 python 和一个数组和 ON DUPLICATE KEY【英文标题】:SQL executemany() with python and an array and ON DUPLICATE KEY 【发布时间】:2021-05-10 08:48:19 【问题描述】:

我正在努力将ON DUPLICATE KEY 与我当前的代码一起使用:

def upload_to_database(ticker_collection):
  trend_data = []
  trend_data_table = "trend_data"
  trend_data_columns = "Ticker, Subreddit, Score, Rockets, Date"
  
  trend_data_sql = "INSERT INTO " + trend_data_table +\
                   " (" + trend_data_columns + ") VALUES (%s, %s, %s, %s, %s) " +\
                   "ON DUPLICATE KEY UPDATE " +\
                   "Score = Score + %s, " +\
                   "Rockets = Rockets + %s"

  for ticker in ticker_collection:
    ticker_subreddit = ticker_collection[ticker]['subreddit']
    ticker_score = int(ticker_collection[ticker]['score'])
    ticker_rockets = int(ticker_collection[ticker]['rockets'])
    insert_date = datetime.date(datetime.now(est))
    
    ticker_data = (ticker, ticker_subreddit, ticker_score, ticker_rockets, insert_date, 1, 1)

    trend_data.append(ticker_data)
  
  the_db_cursor.executemany(trend_data_sql, trend_data)
  the_database.commit()
  
  return the_db_cursor.rowcount, "was inserted."

trend_data_sql 是我的查询,最后有 Score 和 Rockets,如果存在具有相同 Ticker 和 DateTime(我的唯一键)的条目,我只想更新该条目的 score 和 Rockets。

但是,我正在尝试使用 executemany() 执行此操作以节省数据库性能。我对如何将 ON DUPLICATE KEY 与 for 循环和 executemany() 结合起来有点困惑。

任何指导或建议将不胜感激。

表结构:

CREATE TABLE `trend_data` (
  `Ticker` varchar(255) NOT NULL,
  `Subreddit` varchar(255) NOT NULL,
  `Score` int(11) NOT NULL,
  `Rockets` int(11) NOT NULL,
  `Date` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

表索引:

ALTER TABLE `trend_data`
  ADD UNIQUE KEY `Unique_Keys` (`Ticker`,`Date`,`Subreddit`) USING BTREE;

【问题讨论】:

【参考方案1】:

请试试这个:

  trend_data_sql = "INSERT INTO " + trend_data_table +\
                   " (" + trend_data_columns + ") VALUES (%s, %s, %s, %s) " +\
                   "ON DUPLICATE KEY UPDATE " +\ 
                   "Score = Score + %s, " +\
                   "Rockets = Rockets + %s" 

  for ticker in ticker_collection:
    ...

    value = ...

    ...
    
    ticker_data = (ticker, ticker_subreddit, ticker_score, ticker_rockets, value, value)

    trend_data.append(ticker_data)

它在 MariaDB 上进行了测试。如果因为您使用的是 mysql 而无法正常工作,我认为您可以尝试以下方法。 (我无法测试,因为我没有 MySQL...)

  trend_data_sql = "INSERT INTO " + trend_data_table +\
                   " (" + trend_data_columns + ") VALUES (%(ticker)s, %(reddit)s, %(score)s, %(rocket)s, %(date)s) " +\
                   "ON DUPLICATE KEY UPDATE " +\
                   "Score = Score + %(value)s, " +\
                   "Rockets = Rockets + %(value)s"

  for ticker in ticker_collection:
    ...
        
    ticker_data = 
      'ticker': ticker,
      'reddit': ticker_subreddit, 
      'score': ticker_score, 
      'rocket': ticker_rockets, 
      'date': insert_date, 
      'value': 1
        

    trend_data.append(ticker_data)
  
  the_db_cursor.executemany(trend_data_sql, trend_data)
  the_database.commit()
  
  return the_db_cursor.rowcount, "was inserted."


ticker_collection = 
    'a': 'subreddit': 'aa', 'score': 1, 'rockets': 11,
    'b': 'subreddit': 'bb', 'score': 2, 'rockets': 22,
    'c': 'subreddit': 'cc', 'score': 3, 'rockets': 33,
    'd': 'subreddit': 'dd', 'score': 4, 'rockets': 44


print(upload_to_database(ticker_collection))

【讨论】:

@alphadmon 在您的示例中,变量VALUE 是什么?如果还有其他内容,您也应该将它们附加到trend_data @alphadmon 我进行了编辑。请检查一下。 :) @alphadmon 我再次检查了它。它工作正常。请通过复制和粘贴替换您的trend_data_sql,并修改ticker_data。您可以将value 替换为简单的1 来测试它是否有效。 @alphadmon 与我分享您的表架构。而且,您是否将ticker_scoreticker_rockets 重用为values? @alphadmon 我用编辑过的代码进行了测试。它工作正常。我也添加了我的测试用例。请检查您的数据是否与我的数据具有不同的属性。

以上是关于SQL executemany() 与 python 和一个数组和 ON DUPLICATE KEY的主要内容,如果未能解决你的问题,请参考以下文章

在 sql.executemany(... '(' 附近的语法错误

Django:使用带有 executemany 和 MySQL 的自定义原始 SQL 插入

python 在使用 Sql Server 的 fast_executemany 作为 TRUE 时崩溃

使用 pyODBC 的 fast_executemany 加速 pandas.DataFrame.to_sql

Python SQL executemany 语句不起作用

(fast_executemany = True) 错误“[ODBC Driver 17 for SQL Server]强制转换规范 (0) (SQLExecute)'的字符值无效”)