为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 python 编写一个要从多个 sql 表中删除的函数

如何使用 python 编写一个要从多个 sql 表中删除的函数

倚天杖 2022-09-20 17:36:56
我正在实施一个学生数据库项目,该项目具有多个表,例如学生,班级,部分等我写了一个delete_table函数,它采用参数表名和值从特定表中删除一行,但我的代码中似乎存在某种语法错误:def delete_tables(tab_name,attr,value):     c.execute("delete from table=:tab_name where attribute=:attr is value=:value ",{'tab_name':tab_name, 'attr': attr, 'value': value})输入:delete_tables(“部分”,“sec_name”,S1“)错误文本:c.execute(“从表中删除=:tab_name其中属性=:attr 是值=:值”,{'tab_name':tab_name, 'attr', 'value': value})sqlite3.操作错误:靠近“表”:语法错误我已经尝试了所有提到的答案,你们都建议的是,即使它成功了,它也是不安全的。因此,我是否必须编写函数来单独删除每个表,而不是使用单个函数,并且是否有任何其他替代方法,我不需要继续为n个表编写n个函数?????提前致谢 :))
查看完整描述

3 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

问题是你不能对值以外的事物使用参数化查询(即)(不确定我是否使用了正确的术语):表名,列名和SQL关键字是被禁止的:tab_name

  • where age > :max_age还可以。

  • where :some_col > :max_age莫。

  • where age :comparison_operator :max_age是不行的。

现在,您可以使用字符串串联或 f 字符串构建自己的查询,但是...🧨 这是一个巨大的,巨大的SQL注入风险。请参阅 Bobby 表 更不用说,当您必须处理字符、数字或 None 时,将值连接到 SQL 查询字符串中会很快遇到问题。(无 = > NULL,字符需要引号,数字不需要)。

您可以使用字符串替换来构建查询,这些字符串替换仅接受表名和列名的已知值,然后使用 上的参数化查询驱动删除条件值。:value

(虽然这似乎具有限制性,但让随机调用方确定要删除的表根本不安全)。

像这样:

delete_tables(tab_name,attr,value):


   safe_tab_name = my_dict_of_known_table_names[tab_name]


   safe_attr = my_dict_of_known_column_names[attr]


                         # you have to `=`, not `is` here👇 

   qry = f"delete from {safe_tab_name} where {safe_attr} = :value "


   # not entirely sure about SQLite's bind/parametrized syntax.

   # look it up if needed.

   c.execute(qry, dict(value = value))


假设用户只直接输入值,则至少可以防止SQL注入。


查看完整回答
反对 回复 2022-09-20
?
猛跑小猪

TA贡献1858条经验 获得超8个赞

您需要查看将在python方法中执行的确切SQL命令。对于方法调用delete_tables(“部分”、“sec_name”、“S1”),将生成的 SQL 命令将是

delete from table=section where attribute=sec_name is value=S1

这将是 SQL 中的无效命令。正确的命令应该是

delete from section where sec_name='S1'

因此,您需要相应地更改python函数。需要完成的更改应如下所示:

def delete_tables(tab_name, attr, value):
    c.execute("delete from :tab_name where :attr = ':value'",
        {'tab_name': tab_name, 'attr': attr, 'value':value})


查看完整回答
反对 回复 2022-09-20
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

def delete_tables(tab_name, attr, value):
    c.execute("delete from " + tab_name + "where " + attr + " = " + value)

我认为这样的事情会起作用,问题是你试图修改一个属性,但它的名称总是 ,为此你想把它变成一个参数,以便正确处理它。attribute

希望它有所帮助。

编辑:

检查这个SQLite蟒蛇

c.execute的作用是“执行”一个SQL查询,所以,你可以做一些类似你有表的东西。c.execute("select * from clients")clients

execute进行查询并为您带来结果集(如果是这种情况),因此,如果要使用常规SQL查询从表中删除,请在控制台中键入,该语句将删除id等于12的客户端。delete from clients where client_id = 12

现在,如果你在蟒蛇中使用SQLite,你会做的

c.execute("delete from clients where client_id = 12")

但是,正如您希望它适用于任何表和任何字段(属性)一样,它会将表名,字段名称和该字段的值转换为变量。

tableName = "clients"

field = "client_id"

value = "12" #must be string because you would have to cast it from int in the execute

"""

if value is a varchar you must write

value = "'12'" because the '' are needed.

"""

c.execute("delete from " + tableName + " where " + field + " = " + value)


在顶部,您希望它是一个函数


def delete_tables(tableName, field, value):

    c.execute("delete from " + tableName+ "where " + field + " = " + value)

编辑 2:

亚伦的评论是真的,它不安全,下一步你会做的是


def delete_tables(tab_name, attr, value):

    #no ':value' (it limits the value to characters)

    c.execute("delete from :tab_name where :attr = :value",

        {'tab_name': tab_name, 'attr': attr, 'value':value})

这是来自瓦萨尔的答案


查看完整回答
反对 回复 2022-09-20
  • 3 回答
  • 0 关注
  • 149 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信