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_score
和ticker_rockets
重用为value
s?
@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
(fast_executemany = True) 错误“[ODBC Driver 17 for SQL Server]强制转换规范 (0) (SQLExecute)'的字符值无效”)