【问题标题】:Getting value from MySQL and loop over it with if从 MySQL 获取价值并使用 if 循环它
【发布时间】:2013-04-07 15:35:34
【问题描述】:

我有以下代码:

### Write the new userid to the sql database
# Open database connection
db = MySQLdb.connect("sql01.domain1.lan","webuserid","test","webuserid" )
# prepare a cursor object using cursor() method
cursor = db.cursor()



dub_userid = int(userid)
# Check for dublicate of current userid value
sql = "SELECT * FROM webuserid WHERE userid = '"+str(dub_userid)+"'"
try:
        # Execute the SQL command
        cursor.execute(sql)
        # Fetch all the rows in a list of lists.
        results = cursor.fetchone()
        data = cursor.fetchone()
except:
        print "SQL Error: Unable to fetch data"
if data == None:
        print "User doesn't exist - Creating"
else:
        sys.exit("User exists")

# Prepare SQL query to INSERT a record into the database.
sql = """INSERT INTO webuserid(userid)
         VALUES ('"""+userid+"""')"""
try:
        # Execute the SQL command
        cursor.execute(sql)
        # Commit your changes in the database
        db.commit()
except:
        #Rollback in case there is any error
        db.rollback()
# disconnect from server
db.close()

变量userid的字符串值为00001

我想要代码做的是连接到数据库(工作),将 userid 转换为 dub_userid 中的整数,并使用结果值查找重复项。

问题是,当我运行代码时,用户 ID 值为 00001 时会发生以下情况:

  1. 用户 ID 1 已提交到数据库(应该如此,因为没有其他名为 1 的用户 ID)
  2. 下一次运行,用户 ID 1 再次提交到数据库(不应该,因为用户 ID 1 已经存在)
  3. 第三次运行,脚本存在,并显示“用户存在”消息。

我已经尝试过使用数据和数据[1],但似乎无法找出问题所在。

【问题讨论】:

    标签: python mysql python-2.7 constraints unique-constraint


    【解决方案1】:

    你真的想使用字符串插值,而是使用 SQL 参数。接下来,您将获取 两个 行;您真正需要做的就是测试是否有任何行:

    sql = "SELECT * FROM webuserid WHERE userid = %s"
    
    try:
        # Execute the SQL command
        cursor.execute(sql, (dub_userid,))
        found = cursor.rowcount
    except:
        print "SQL Error: Unable to fetch data"
    if not found:
        print "User doesn't exist - Creating"
    else:
        sys.exit("User exists")
    
    sql = """INSERT INTO webuserid(userid)
             VALUES (%s)"""
    try:
        # Execute the SQL command
        cursor.execute(sql, (userid,))
        # Commit your changes in the database
        db.commit()
    except:
        #Rollback in case there is any error
        db.rollback()
    # disconnect from server
    db.close()
    

    这可以进一步简化;您可以使用db 作为上下文管理器来自动提交或在失败时回滚:

    with db:
        cursor.execute(sql, (userid,))
    
    db.close()
    

    【讨论】:

    • 非常感谢!这确实有效!由于可能的 SQL 注入,不应该使用字符串插值吗?
    • 没错,SQL 参数在正确引用数据以及在需要时提供转换方面做得更好。
    • 再次感谢,我将查看我的代码并使用 %s 而不是插值:)
    【解决方案2】:

    这个问题可以而且应该通过向表中添加一个 UNIQUE 约束来解决,而不是通过编写 Python 代码。如果您尝试通过编写 Python 代码来强制执行约束,仍然有可能有人通过其他方法插入数据。如果添加约束,则该约束由数据库本身强制执行。

    ALTER TABLE tablename ADD UNIQUE indexname (userid)
    

    添加此约束后,如果违反了约束,INSERT 语句将引发异常。您可以将cursor.execute 包裹在try...except 中以处理违规行为。

    如果你的表已经有违反约束的行,那么

    ALTER IGNORE TABLE tablename ADD UNIQUE indexname (userid)
    

    将添加约束删除所有违反约束的行(为每个唯一的 useid 保留一行)。

    【讨论】:

    • 不知道 mysql 可以做到这一点。我会在我的数据库中更改它。谢谢!
    猜你喜欢
    • 2021-08-14
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多