13

我正在创建一个连接到 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菜鸟,谢谢大家。

4

4 回答 4

21

我相信最有效的“它是否存在”查询只是做一个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,因此您可以执行布尔真值测试。

更新

实际上,只使用行数甚至不获取结果会更快:

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().

于 2012-11-14T06:21:35.073 回答
3

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

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

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)。

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

于 2012-11-14T13:49:40.840 回答
1

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

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'

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

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

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

于 2012-11-14T06:11:45.297 回答
0

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

因此,而不是 2 个语句:

 Query MySQL for exists:
     Query MySQL insert data

只需做 1 ,它只有在它是唯一的时候才会起作用:

Query MySQL insert data

1 查询优于 2。

于 2014-01-11T03:49:47.040 回答