mysql - 如何在插入 MySQL 数据库之前以编程方式检查重复行
问题描述
我是一名数据库新手,正在使用日终股票数据学习 python3.7 和 mysql。我设法以编程方式将数据加载到数据库中。但是,我想避免插入重复的行。我正在逐行解析文本文件。
到目前为止,这是我的代码。
import pymysql
import pandas as pd
import sys
ticker_file = 'C:/testfile.txt'
# Read the text file and add , to the end of the line.
def fun_read_file(ticker_file):
host = 'localhost'
user = 'user'
password = 'password'
db = 'trading'
with open(ticker_file, 'r') as f:
for line in f:
# Do something with 'line'
stripped = line.strip('\n\r')
value1,value2,value3,value4,value5,value6,value7 = stripped.split(',')
print(value1,value2,value3,value4,value5,value6,value7)
# Call the csv_to_mysql function
csv_to_mysql(host, user, password, db, value1, value2, value3, value4, value5, value6, value7)
def csv_to_mysql(host, user, password, db, value1, value2, value3, value4, value5, value6, value7):
'''
This function load a csv file to MySQL table according to
the load_sql statement.
'''
load_sql = 'INSERT INTO asx (Symbol,Date,Open,High,Low,Close,Volume) VALUES (%s, %s, %s, %s, %s, %s, %s)'
args = [value1, value2, value3, value4, value5, value6, value7]
print('You are in csv_to_mysql')
print(args)
try:
con = pymysql.connect(host=host,
user=user,
password=password,
db=db,
autocommit=True,
local_infile=1)
print('Connected to DB: {}'.format(host))
# Create cursor and execute Load SQL
cursor = con.cursor()
cursor.execute(load_sql, args)
print('Successfully loaded the table from csv.')
con.close()
except Exception as e:
print('Error: {}'.format(str(e)))
sys.exit(1)
# Execution the script
fun_read_file(ticker_file)
这是名为 asx 的表中的当前数据:
mysql> select * from asx;
+--------+------------+--------+--------+--------+--------+---------+
| Symbol | Date | Open | High | Low | Close | Volume |
+--------+------------+--------+--------+--------+--------+---------+
| 14D | 2019-01-11 | 0.2950 | 0.2950 | 0.2750 | 0.2750 | 243779 |
| 14D | 2019-01-11 | 0.2950 | 0.2950 | 0.2750 | 0.2750 | 243779 |
| 14D | 2019-01-11 | 0.2950 | 0.2950 | 0.2750 | 0.2750 | 243779 |
| 14DO | 2019-01-11 | 0.0700 | 0.0700 | 0.0700 | 0.0700 | 0 |
| 1AD | 2019-01-11 | 0.2400 | 0.2400 | 0.2400 | 0.2400 | 0 |
| 1AG | 2019-01-11 | 0.0310 | 0.0320 | 0.0310 | 0.0310 | 719145 |
| 1AL | 2019-01-11 | 0.9100 | 0.9100 | 0.9100 | 0.9100 | 0 |
| 1ST | 2019-01-11 | 0.0280 | 0.0280 | 0.0280 | 0.0280 | 0 |
| 3DP | 2019-01-11 | 0.0500 | 0.0560 | 0.0500 | 0.0520 | 3919592 |
+--------+------------+--------+--------+--------+--------+---------+
9 rows in set (0.02 sec)
可以看到,前三行数据都是重复的。我有大量这些文件要导入,重复行的可能性很高。有没有办法检查我要插入的行在表中是否不存在?检查符号和日期值应该足以确保此数据集的唯一性。但我不确定如何做到这一点。
在此先感谢您的帮助。
为澄清而添加:非常感谢您迄今为止的投入。
我已经阅读了主键回复,并有关于它们的后续问题。我的理解是主键在表中必须是唯一的。由于日终股票数据的性质,我最终可能会得到以下行。
+--------+------------+--------+--------+--------+--------+---------+
| Symbol | Date | Open | High | Low | Close | Volume |
+--------+------------+--------+--------+--------+--------+---------+
| 14D | 2019-01-12 | 0.3000 | 0.4950 | 0.2950 | 0.4900 | 123456 |
| 14D | 2019-01-11 | 0.2950 | 0.2950 | 0.2750 | 0.2750 | 243779 |
| 14D | 2019-01-11 | 0.2950 | 0.2950 | 0.2750 | 0.2750 | 243779 |
| 14DO | 2019-01-11 | 0.0700 | 0.0700 | 0.0700 | 0.0700 | 0 |
| 1AD | 2019-01-11 | 0.2400 | 0.2400 | 0.2400 | 0.2400 | 0 |
如您所见,Symbol 14D 每个日期都有一行。第 1 行中的数据有效。但是,第 2 行和第 3 行是重复的。我需要删除第 2 行或第 3 行以保持表格准确。
在这种情况下,我还应该制作符号和日期主键吗?
解决方案
我建议您阅读MySQL 的INSERT IGNORE,ON DUPLICATE KEY UPDATE关键字,并查看PRIMARY KEY和UNIQUE约束。
这是一个可以解决您的问题的快速链接: Mysql 处理重复项
如果你还有问题,我可以回答。
推荐阅读
- sql - 如何在 SQL 查询中使用 Row_Number
- javascript - 如何在闪亮的应用程序中观察 JavaScript 按钮
- graphics - 是否能够在一个包含一个管道的渲染通道中调用 vkCmdDrawIndexed 的多个绘制调用?
- javascript - 加载页面时出错(在引导模板的 js 上)
- bash - 无法使用包含点的键从 bash 脚本中获取 jq 命令
- firebase - 扑动 Firebase 动画列表视图如何将数据传递到详细信息屏幕
- algorithm - 为什么 √n 是跳跃搜索中 m 的最优值?
- php - Laravel 中的 Xdebug 不适用于 VSCode
- android - 在 Android 上使用 WebRTC 添加本机放大/缩小功能和其他相机本机功能
- reactjs - 如果在if下怎么写jsx?