1

我的表bank有三列:uid、nick 和 balance。

我可以很好地插入新行,但是nick由于uid自动递增,因此很容易出现重复的行,从而使每一行都是唯一的。但是我不希望这样,我只想要一个每一行nick

    target = input.group(2)

    cursor.execute ("INSERT INTO bank (nick, balance) VALUES('" + db.escape_string(target.lower()) + "', 5)")
    db.commit()

    bot.say('An account for ' + target + ' has been created.')

到目前为止,这是我的代码,但是我不确定如何创建SELECT查询,然后nick在插入新行之前检查表中是否已经存在。

4

4 回答 4

3

我会采用不同的方法。我会在列的数据库级别添加一个唯一nick约束:

ALTER TABLE bank ADD UNIQUE (nick);

在您的 Python 代码中,然后放置一个tryandexcept来适当地处理违反唯一约束的异常。

于 2012-04-13T15:38:34.390 回答
0

拥有那个递增的 ID 听起来没有意义。
相反,请考虑帐户的唯一标识符,例如帐号。
正如另一个答案所暗示的那样,在 上添加唯一约束的危险nick在于,随着人口的增长,您可能会有两个或更多人希望使用相同的nick.

此外,您应该将要插入的值作为第二个参数传递execute()给,至少有两个原因*。

cursor.execute("""INSERT INTO bank (nick, balance) 
                  VALUES (%s, %s);""", (target.lower(), 5))

*两个原因是:

  1. 您不必手动处理任何报价问题。Mysql-Python 会为你解决这个问题。
  2. 您避免了 SQL 注入攻击的可能性。

请注意:参数占位符适用%s于所有类型的参数,而不仅仅是字符串。所以你不需要做任何事情,比如%d插入一个整数。

于 2012-04-13T15:36:03.297 回答
0

我想你正在使用 psycopg2

cursor.execute ("SELECT * FROM bank WHERE nick = %s",[nick])

nick = cursor.fetchall()

如果尼克...

于 2012-04-13T15:37:45.373 回答
0

我正在使用 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() 本身对于防止“未读记录”错误是必要的,因为如果找到记录,它会从游标中清除数据。

于 2019-01-22T10:24:58.400 回答