从MySQL获取价值并使用if循环

时间:2013-04-07 15:35:35

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

我有以下代码:

### 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中的整数,并使用结果值来查找dublicate。

问题是,当我运行代码时,并且,当userid值为00001时,会发生以下情况:

  1. 用户ID 1被提交到数据库(因为它没有,因为没有其他用户ID被称为1
  2. 接下来运行,再次将用户ID 1提交到数据库(不应该,因为用户ID 1已经存在)
  3. 第三次运行,脚本与" User exists"存在。应该留言。
  4. 我已经尝试了数据和数据[1],但似乎无法找出错误。

2 个答案:

答案 0 :(得分:2)

你真的想要使用字符串插值,而是使用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()

答案 1 :(得分:1)

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

ALTER TABLE tablename ADD UNIQUE indexname (userid)

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

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

ALTER IGNORE TABLE tablename ADD UNIQUE indexname (userid)

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