Je suis un débutant en base de données et j'apprends sur python3.7 et mysql en utilisant les données de stock de fin de journée. J'ai réussi à charger des données par programme dans la base de données. Cependant, je veux éviter d'insérer des lignes en double. J'analyse un fichier texte ligne par ligne.
Voici mon code pour le moment.
+--------+------------+--------+--------+--------+--------+---------+ | 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 |
Et voici les données actuelles dans le tableau appelé 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)
Comme vous pouvez le voir, les trois premières lignes de données sont toutes des doublons. J'ai une tonne de ces fichiers à importer, et les chances de doublons sont élevées. Existe-t-il un moyen de vérifier que la ligne que je vais insérer n'existe pas déjà dans le tableau? La vérification des valeurs de symbole et de date devrait être suffisante pour garantir l'unicité de cet ensemble de données. Mais je ne sais pas comment y parvenir.
Merci d'avance pour votre aide.
Ajouté pour clarification: Merci beaucoup pour votre contribution jusqu'à présent.
J'ai lu les réponses de la clé primaire et j'ai des questions complémentaires à leur sujet. Je crois comprendre que les clés primaires doivent être uniques à l'intérieur d'une table. En raison de la nature des données de stock de fin de journée, je peux me retrouver avec les lignes suivantes.
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)
Comme vous pouvez le voir, le symbole 14D aura une ligne pour chaque date. Les données de la ligne 1 sont valides. Cependant, les lignes 2 et 3 sont des doublons. Je devrais supprimer la ligne 2 ou 3 pour que le tableau reste précis.
Dans ce scénario, dois-je quand même créer des clés primaires de symbole et de date?
3 Réponses :
Je vous suggère de lire les mots clés INSERT IGNORE , ON DUPLICATE KEY UPDATE pour MySQL, ainsi que de rechercher PRIMARY KEY et UNIQUE contraintes.
Voici un lien rapide qui peut résoudre votre problème: Mysql Gestion des doublons
Si vous avez encore des questions, je peux y répondre.
Merci beaucoup pour votre aide. J'ai publié des questions de suivi ci-dessus concernant votre proposition de réponse. Pourriez-vous s'il vous plaît passer en revue et laissez-moi savoir. Ta.
Je suis encore un débutant en Python, mais je connais les bases de données. Ce que je ferais, c'est d'abord faire une requête SELECT pour vérifier si un enregistrement avec le symbole et la date donnés existe dans la table MySQL, et n'effectuer l'INSERT que si le SELECT a renvoyé 0 lignes. Vous devriez également envisager de faire de ces deux colonnes votre clé primaire pour cette table. Cela garantira qu'aucun doublon n'est inséré (mais l'insertion d'un duplicata peut déclencher une exception qui doit être gérée).
Merci beaucoup pour votre aide. J'ai posté des questions de suivi ci-dessus concernant votre proposition de réponse. Pourriez-vous s'il vous plaît passer en revue et laissez-moi savoir. Ta.
La sélection serait redondante
J'ai réussi à résoudre le problème. J'ai publié le code de travail ci-dessus.
Merci de nous avoir informés de la manière de répondre correctement. J'ai fini par créer une nouvelle fonction appelée check_row et utilisé une instruction de sélection pour vérifier si la ligne existe déjà. Dans cet ensemble de données, je n'ai besoin que de vérifier si une ligne du tableau contient déjà valeur1 (symbole) et valeur2 (date) afin de garder les données exactes. Merci tutiplain de m'avoir indiqué dans cette direction.
import pymysql
import pandas as pd
import sys
ticker_file = 'C:/test.txt'
# Read the text file and add , to the end of the line.
def fun_read_file(ticker_file):
#load_sql = "LOAD DATA INFILE 'C:/test.txt' INTO TABLE asx FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';"
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 check_row function
check_row(host, user, password, db, value1, value2, value3, value4, value5, value6, value7)
# Insert row into table
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]
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)
# Check for duplicate row before insertion into table
def check_row(host, user, password, db, value1, value2, value3, value4, value5, value6, value7):
# Manipulate the value2 (date) string first 20190111 into 2019-01-11
str_value2 = value2
year = str_value2[:4]
day = str_value2[-2:]
month = str_value2[4:6]
str_query_value2 = year + '-' + month + '-' + day
print(str_query_value2)
# Select statement to query whether row already exists
query = 'SELECT COUNT(*) from asx WHERE Symbol = %s AND Date = %s'
args = [value1, str_query_value2]
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(query, args)
print('Successfully queried the asx table.')
result = cursor.fetchall()
print(result)
# Fetchall method outputs a tuple. Access first item of the first tuple.
int_result = result[0][0]
print(int_result)
con.close()
if int_result >= 1:
# Exit this function, 0 means clean exit, 1 means abort
exit(0)
else:
# Call the csv_to_mysql function
csv_to_mysql(host, user, password, db, value1, value2, value3, value4, value5, value6, value7)
except Exception as e:
print('Error: {}'.format(str(e)))
sys.exit(1)
# Execution the script
fun_read_file(ticker_file)
Voici le code complet ci-dessous.
query = 'SELECT COUNT(*) from asx WHERE Symbol = %s AND Date = %s' args = [value1, str_query_value2]