首页 > 解决方案 > 如何在插入 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 行以保持表格准确。

在这种情况下,我还应该制作符号和日期主键吗?

标签: mysqlpython-3.x

解决方案


我建议您阅读MySQL 的INSERT IGNOREON DUPLICATE KEY UPDATE关键字,并查看PRIMARY KEYUNIQUE约束。

这是一个可以解决您的问题的快速链接: Mysql 处理重复项

如果你还有问题,我可以回答。


推荐阅读