如何在 python MySQL 中使用“SELECT”查询查找行是否存在?

问题描述 投票:0回答:1

我想使用

SELECT
查询检查数据库中是否存在特定行。如果没有,我想用另一个查询来
INSERT INTO
数据库。如果是的话,我不希望发生任何事情。

我正在考虑在Python中使用if语句来处理上面的场景,但是我找不到如何使

SELECT
查询根据是否找到该行返回True或False。

我正在使用MySQLdb

   def _query (self, query):
     cursor = self.db.cursor()
     cursor.execute (query)
     return cursor

      for k,v in sorted(config.items()):
  
    #checking for duplicate values
  
    check_items_table = "SELECT * FROM items WHERE text = ('%s') AND name = ('%s')" % \
    (str (k), str (v))
    self._query (check_items_table)
  
    if check_items_table == <True or False or Something>:

      #do nothing

    else:

      #insert into items table

      items_table = "INSERT INTO items(item_id, \
      name, text) \
      VALUES (null,'%s', '%s')" % \
      (str (k), str (v))
      self._query (items_table)
python mysql mysql-python
1个回答
3
投票

您正在使用 MySQLdb,它符合 DB-API 2.0 标准。

您正在调用

execute
,然后返回
Cursor
对象。

游标有一个属性

rowcount
,但在某些数据库模块中,该属性仅针对修改查询(如
INSERT
UPDATE
)设置,不适用于
SELECT
,而在其他数据库模块中,仅在执行
 后设置。 fetch*
操作。 (我相信 MySQLdb 是后者之一,但我并不肯定。)

所以,你想要的是调用

fetchone
方法。如果它返回一行,则该行存在;如果引发异常,则该行不存在。


或者,您可以

SELECT COUNT(*) FROM …
,而不是选择行本身。然后
fetchone
保证返回一行只有一个值,该值要么是 0 要么 1。


但是,我不确定您一开始就想这样做。通常,最好在一个或多个列上创建唯一约束,这样数据库就不允许该列存在具有相同值的两行。然后,你可以直接

INSERT
该行,如果它已经存在,你会得到一个错误;根本不需要
SELECT
。 (或者,如果您不需要知道它是否已经存在,您可以使用
INSERT IGNORE
,这是 MySQL 特定的。)


同时,扩展我的旁注:

动态构建 SQL 字符串总是一个坏主意,如下所示:

items_table = "INSERT INTO items(item_id, \
      name, text) \
      VALUES (null,'%s', '%s')" % \
      (str (k), str (v))

这会让您面临SQL注入,迫使您处理繁琐的引用/转义/类型转换问题,并阻止数据库意识到您正在重复运行相同的查询。

改用参数化语句。像这样:

items_table = "INSERT INTO items(item_id, \
      name, text) \
      VALUES (null, %s, %s)"

请注意,我没有引用

%s
,也没有使用
%
运算符。这些值被发送到
execute
语句:

cursor.execute(items_table, (k, v))

所以,你只需要像这样更新你的

_query
包装器:

def _query(self, query, parameters=[]):
     cursor = self.db.cursor()
     cursor.execute(query, parameters)
     return cursor

...你可以这样称呼它:

self._query(items_table, (k, v))
© www.soinside.com 2019 - 2024. All rights reserved.