Python-将datetime参数传递到SQL命令

时间:2019-08-23 17:01:37

标签: python sql-server pandas pyodbc

我正在尝试在Python中做类似的事情,

JSONObject jsonObject = new JSONObject(response);
JSONObject snippet = jsonObject.getJSONObject("items");
String t = snippet.getString("rating");

SQLCommand = ("Delete From %s where [Date] >= %s and [Date] <= %s", (calendar_table_name, required_starting_date, required_ending_date)) cursor.execute(SQLCommand) calendar_table_name变量

stringrequired_starting_date变量

datetimerequired_ending_date变量

尝试此操作会给我一个错误:

  

要执行的第一个参数必须是字符串或Unicode查询。

尝试了这个,它给了我同样的错误:

datetime

编辑:

SQLCommand = ("Delete From " +  calendar_table_name + " where [Date] >= %s and [Date] <= %s", ( required_starting_date, required_ending_date))

cursor.execute(SQLCommand)

这对我来说在SSMS中有效,

type(required_ending_date)

Out[103]: pandas._libs.tslibs.timestamps.Timestamp


type(required_starting_date)

Out[103]: pandas._libs.tslibs.timestamps.Timestamp

更新:-这是我正在尝试的代码

  delete from [table_test] where [Date] >= '2007-01-01' and [Date] <= '2021-01-01';

required_starting_date和required_ending_date为“时间戳记”格式

Delete_SQLCommand =  f"Delete FROM [{calendar_table_name}] WHERE [Date]>=? And [Date]<=?"
params = (required_starting_date, required_ending_date)

3 个答案:

答案 0 :(得分:1)

您没有说要使用哪个库进行SQL访问,但这是使用psycopg的安全示例。

from psycopg2 import sql

cmd = sql.SQL("delete from {} where date >= %s and date <= %s")
table_name = sql.Identifier(calendar_table_name)
cur.execute(
    cmd.format(table_name),
    [required_starting_date, required_ending_date]
)

请注意,这不是 str.format,而是SQL.format。该库确保calendar_table_name是正确的列名,并且SQL.format确保在生成有效的参数化查询之前,它已正确地合并到命令模板中。


如果没有适当的库支持,您将需要进行某种的动态查询生成。但是,它应该是 restricted 排序,限制越多越好。最安全的方法是从硬编码查询的查找表开始:

queries = {
  'name1': 'delete from name1 where ... ',
  'name2': 'delete from name2 where ...',
}

这样,您不能构造一个用于查询任意表名的查询,只能选择一个预先构造的查询。

第二个方法是将构造函数包装在一个函数中,该函数首先检查有效的表名。例如,

def generate_query(table_name):
    if table_name not in ['name1', 'name2', ...]:
        raise ValueError("Invalid table name")

    return "delete from {} where ...".format(table_name)

答案 1 :(得分:1)

pyodbc可以将熊猫的jtc值作为正确的参数化查询的输入来处理:

Timestamp

答案 2 :(得分:0)

此代码有3个(至少)不同的问题:

  1. 您使用的是熊猫时间戳类型,而不是预期的python datetime类型。 Roganosh answer explains that
  2. 您正在将sql标识符(表名)与sql值(日期)混合在一起。您只能将值作为参数传递给cursor.executesee chepner's answer.
  3. 您使用错误的参数调用cursor.execute

cursor.execute需要两个参数。由于您的SQLCommand变量是一个元组,因此调用*时,可以使用cursor.execute将查询字符串和变量解压缩为两个参数。

SQLCommand = (
    "DELETE FROM table_name WHERE date >= %s", 
    (datetime.date(2019, 08, 23),) 
)

cursor.execute(*SQLCommand)

请注意,您不能将诸如表名之类的sql标识符作为参数传递给cursor.execute方法。 The Python Database API Specification没有指定如何使用动态标识符(例如列或表名)构造查询。