如何使用 python 编写一个函数从多个 sql 表中删除
How to write one function to delete from multiple sql tables using python
我正在实施一个包含多个 table 的学生数据库项目,例如学生、class、部分等
我写了一个 delete_table 函数,它采用参数 table 名称和值来从特定 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('section','sec_name','S1')
错误文本:
c.execute("delete from table=:tab_name where attribute=:attr is value=:value ",{'tab_name':tab_name,'attr':属性,'value':值})
sqlite3.OperationalError: near "table": syntax error
我已经尝试了所有提到的答案,你们的建议是,即使成功了,它也将是不安全的。那么我是否必须编写函数来单独删除每个 table,而不是只删除一个函数,是否还有其他替代方法可以解决这个问题,我不需要继续为 n 个 [=38= 编写 n 个函数]s??????
提前致谢:))
def delete_tables(tab_name, attr, value):
c.execute("delete from " + tab_name + "where " + attr + " = " + value)
我认为类似的东西会起作用,问题是您正在尝试修改属性,但它的名称始终是 attribute
,因此您希望将其作为参数以便正确处理它。
希望对您有所帮助。
编辑:
勾选这个SQLite python
c.execute 所做的是 'execute' 一个 SQL 查询,因此,如果您有 clients
table.
execute
进行查询并为您带来结果集(如果是这样的话),因此如果您想使用普通的 SQL 查询从 table 中删除您将在控制台中键入 delete from clients where client_id = 12
并且该语句将删除 id 等于 12.
的客户端
现在,如果您在 python 中使用 SQLite,您将
c.execute("delete from clients where client_id = 12")
但正如您希望的那样,对于任何 table 和任何字段(属性),它会变成 table 名称,字段名称和该字段的值是变量。
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:
aaron's评论是真的,不安全,下一步你要做的是
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})
来自Vatsal's回答
您需要查看将在 python 方法中执行的确切 SQL 命令。
对于方法调用 delete_tables('section', '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})
问题是您不能对值以外的事物使用参数化查询(:tab_name
)(?不确定我使用的是正确的术语):table 名称、列名称SQL 关键字是 禁止的 。
where age > :max_age
可以。
where :some_col > :max_age
不是。
where age :comparison_operator :max_age
不行。
现在,您可以 使用字符串连接或 f 字符串构建您自己的查询,但是...这是一个巨大的 SQL 注入风险。请参阅 Bobby Tables 更不用说将值连接到 SQL 查询字符串中,当您必须处理字符、数字或 None 时,很快就会遇到问题。 (None => NULL,字符需要引号,数字不需要)。
您可以使用仅接受 table 和列名称的已知值的字符串替换来构建查询,然后使用 :value
.[=17 上的参数化查询驱动删除条件值=]
(虽然这看起来有限制,但让随机调用者决定删除哪些 table 至少是不安全的)。
类似于:
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 注入。
我正在实施一个包含多个 table 的学生数据库项目,例如学生、class、部分等
我写了一个 delete_table 函数,它采用参数 table 名称和值来从特定 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('section','sec_name','S1')
错误文本:
c.execute("delete from table=:tab_name where attribute=:attr is value=:value ",{'tab_name':tab_name,'attr':属性,'value':值})
sqlite3.OperationalError: near "table": syntax error
我已经尝试了所有提到的答案,你们的建议是,即使成功了,它也将是不安全的。那么我是否必须编写函数来单独删除每个 table,而不是只删除一个函数,是否还有其他替代方法可以解决这个问题,我不需要继续为 n 个 [=38= 编写 n 个函数]s?????? 提前致谢:))
def delete_tables(tab_name, attr, value):
c.execute("delete from " + tab_name + "where " + attr + " = " + value)
我认为类似的东西会起作用,问题是您正在尝试修改属性,但它的名称始终是 attribute
,因此您希望将其作为参数以便正确处理它。
希望对您有所帮助。
编辑:
勾选这个SQLite python
c.execute 所做的是 'execute' 一个 SQL 查询,因此,如果您有 clients
table.
execute
进行查询并为您带来结果集(如果是这样的话),因此如果您想使用普通的 SQL 查询从 table 中删除您将在控制台中键入 delete from clients where client_id = 12
并且该语句将删除 id 等于 12.
现在,如果您在 python 中使用 SQLite,您将
c.execute("delete from clients where client_id = 12")
但正如您希望的那样,对于任何 table 和任何字段(属性),它会变成 table 名称,字段名称和该字段的值是变量。
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:
aaron's评论是真的,不安全,下一步你要做的是
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})
来自Vatsal's回答
您需要查看将在 python 方法中执行的确切 SQL 命令。 对于方法调用 delete_tables('section', '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})
问题是您不能对值以外的事物使用参数化查询(:tab_name
)(?不确定我使用的是正确的术语):table 名称、列名称SQL 关键字是 禁止的 。
where age > :max_age
可以。where :some_col > :max_age
不是。where age :comparison_operator :max_age
不行。
现在,您可以 使用字符串连接或 f 字符串构建您自己的查询,但是...这是一个巨大的 SQL 注入风险。请参阅 Bobby Tables 更不用说将值连接到 SQL 查询字符串中,当您必须处理字符、数字或 None 时,很快就会遇到问题。 (None => NULL,字符需要引号,数字不需要)。
您可以使用仅接受 table 和列名称的已知值的字符串替换来构建查询,然后使用 :value
.[=17 上的参数化查询驱动删除条件值=]
(虽然这看起来有限制,但让随机调用者决定删除哪些 table 至少是不安全的)。
类似于:
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 注入。