如何使用Python MySQldb检查记录是否存在

时间:2012-11-14 06:06:17

标签: python mysql mysql-python

我正在创建一个连接到mysql的python程序。

我需要检查一个表是否包含数字1以表明它已成功连接,这是我的代码到目前为止:

xcnx.execute('CREATE TABLE settings(status INT(1) NOT NULL)')
  xcnx.execute('INSERT INTO settings(status) VALUES(1)')
  cnx.commit()
  sqlq = "SELECT * FROM settings WHERE status = '1'"
  xcnx.execute(sqlq)
  results = xcnx.fetchall()
  if results =='1':
    print 'yep its connected'
  else:
    print 'nope not connected'
我错过了什么?我是一个sql noob,谢谢你们。

4 个答案:

答案 0 :(得分:15)

我认为最有效的“它存在”查询只是做count

sqlq = "SELECT COUNT(1) FROM settings WHERE status = '1'"
xcnx.execute(sqlq)
if xcnx.fetchone()[0]:
    # exists

如果结果产生任何匹配,则只是要求数据库返回1或0,而不是要求数据库对字段或行执行任何计数操作。这样可以更有效地返回实际记录并计算客户端数量,因为它可以节省双方的序列化和反序列化以及数据传输。

In [22]: c.execute("select count(1) from settings where status = 1")
Out[22]: 1L  # rows

In [23]: c.fetchone()[0]
Out[23]: 1L  # count found a match

In [24]: c.execute("select count(1) from settings where status = 2")
Out[24]: 1L  # rows

In [25]: c.fetchone()[0]
Out[25]: 0L  # count did not find a match

count(*)将与count(1)相同。在您的情况下,因为您正在创建一个新表,它将显示1个结果。如果你有10,000个匹配,它将是10000.但是你在测试中关心的是它是否不是0,所以你可以进行一个bool真值测试。

<强>更新

实际上,使用rowcount甚至更快,甚至没有获取结果:

In [15]: if c.execute("select (1) from settings where status = 1 limit 1"): 
            print True
True

In [16]: if c.execute("select (1) from settings where status = 10 limit 1"): 
            print True

In [17]: 

这也是django的ORM如何做queryObject.exists()

答案 1 :(得分:2)

如果您只想检查是否已成功建立连接,那么为什么要尝试创建表,插入行,然后从中检索数据?

您可以简单地执行以下操作...

sqlq = "SELECT * FROM settings WHERE status = '1'"
xcnx.execute(sqlq)
results = xcnx.fetchone()
if results =='1':
  print 'yep its connected'
else:
  print 'nope not connected'

实际上,如果您的程序到目前为止没有抛出异常,则表示您已成功建立连接。 (请检查上面的代码,我不确定fetchone在这种情况下是否会返回元组,字符串或int)。

顺便说一下,如果由于某种原因你确实需要创建表格,我建议你在退出之前删除它,以便你的程序第二次成功运行。

答案 2 :(得分:1)

运行results = xcnx.fetchall()时,返回值是包含行值的元组序列。因此,当您检查是否results == '1'时,您试图将序列与常量进行比较,该常量将返回False。在您的情况下,将返回单行值0,因此您可以尝试:

results = xcnx.fetchall()
# Get the value of the returned row, which will be 0 with a non-match
if results[0][0]:
  print 'yep its connected'
else:
  print 'nope not connected'

您也可以使用DictCursor(在创建游标时使用.cursor(MySQLdb.cursors.DictCursor),这会使代码更容易解​​释,但结果是相同的:

if results[0]['COUNT(*)]':
    # Continues...

此外,在这种情况下并不是什么大问题,但您要将整数值与字符串进行比较。 MySQL将进行类型转换,但您可以使用SELECT COUNT(*) FROM settings WHERE status = 1并保存(非常小的)处理。

答案 3 :(得分:0)

我最近提高了效率,而不是查询select,只是将一个主索引添加到唯一列,然后添加它。如果它不存在,MySQL只会添加它。

所以而不是2个陈述:

 Query MySQL for exists:
     Query MySQL insert data

只做1,只有它是唯一的才能起作用:

Query MySQL insert data

1查询优于2。