我正在使用 Python (3.6) 和 MySql,我想在添加记录之前检查它们。这是我的代码:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="user",
passwd="password",
database='football'
)
mycursor = mydb.cursor()
def write_to_db(db_table, col_list, data_list, *supply_id):
"""
Takes a record, checks if it already exists and if not inserts it, returning its index or None
:param db_table: name of table to be checked / inserted into
:param col_list: column/field names in a list eg. ['meat', 'sides']
:param data_list: data to be found or inserted eg ['spam', 'eggs']
:param supply_id: Only if you supply calculated id as tuple ('table_id', table_id_val)
:return: If lists don't match =None Else =Index of found record or Index of inserted one
"""
if len(col_list) != len(data_list) or len(col_list) == 0: # List lengths must match
return None # Otherwise returned index is None
# Build search SQL - Select - table - Where - match conditions
find_existing_sql = 'SELECT * FROM {} '.format(db_table) # Which table
find_existing_sql += 'WHERE {} = {} '.format(col_list[0], data_list[0])
sql_end = ' LIMIT 1 ;'
if len(col_list) > 1: # Provided record has more than 1 column
and_sql = ' AND {} = {} ' # add extra match condition for each column
for indx in list(range(1, len(col_list))):
find_existing_sql += and_sql.format(col_list[indx], data_list[indx])
find_existing_sql += sql_end # Complete SQL to find given record
my_cursor.execute(find_existing_sql) # Query database with SQL
seek_response = my_cursor.fetchall() # Read the seek a record response
record_exists = len(seek_response) > 0 # Length = 0 not found, > 0 found
if record_exists:
return seek_response[0][0] # Return id = the first item from the first list of items
else:
# Build insert SQL - Insert into - table - column names - values
insert_sql = 'INSERT INTO {} ('.format(db_table) # Which table
if supply_id is not None: # If you supplied an index
id_col = supply_id[0][0] # first item in first arg = index name
id_val = supply_id[0][1] # second item in first arg = index value
col_list =[id_col] + col_list # Add index column name on the front of column list
data_list = [id_val] + data_list # Add index value on front of data_list
first_col = '{}'.format(col_list[0]) # Start listing columns
more_cols_vals = ', {}' # To add more coumns/values if needed
values_sql = ') VALUES ( {} '.format(data_list[0]) # Start listing values
end_sql = ' );'
insert_cols_sql = insert_sql + first_col
if len(col_list) > 1:
for indx in list(range(1, len(col_list))):
insert_cols_sql += more_cols_vals.format(col_list[indx])
values_sql += more_cols_vals.format(data_list[indx])
# Put Insert SQL together
insert_new_sql = insert_cols_sql + values_sql + end_sql
my_cursor.execute(insert_new_sql) # Insert the new record into db
mydb.commit()
if supply_id is not None: # If you supplied an index
return id_val # Return that
else: # if not
return my_cursor.lastrowid # Return auto-generated index
如果您提供自己生成的索引,此函数将获取表名、列名列表、要插入的值列表和可选元组
('table_id', table_id_value)
但是如果你不提供这个元组,MySQL 将使用自动生成的索引进行插入。该例程假定您的表将索引作为其第一列。
如果找到的记录已存在,则返回该记录的索引,如果记录不存在,则返回插入记录时使用的索引。索引要么是 MySQL 生成的,要么是您提供的。如果您的列名列表和值列表长度不匹配,它将返回 None。
我已经使用 Python 来构建 SQL 语句,因此您可以拥有可变数量的列。您可以在 SQL 中传递值(尽管我不知道如何为可变数量的列和值执行此操作),但我不断收到“参数数量错误”的错误,并且使用 Python 的 string.format() 解决了这个问题。
*supply_id(通常是 *args)参数是一个列表,即使您只提供一个元组,所以我需要两个索引来访问第一个 arg,然后是 0 或 1 来访问元组中的列名和值。
.fetchall() 本身对于防止“未读记录”错误是必要的,因为如果找到记录,它会从游标中清除数据。