Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 由于在形成SQL查询时不支持字符串替换,如何动态分配表名?_Python_Sqlite - Fatal编程技术网

Python 由于在形成SQL查询时不支持字符串替换,如何动态分配表名?

Python 由于在形成SQL查询时不支持字符串替换,如何动态分配表名?,python,sqlite,Python,Sqlite,sqlite3还很陌生,所以请在这里耐心听我说 我希望有一个可以传递表名和要更新的值的函数 我最初是这样开始的: def add_to_table(table_name, string): cursor.execute('INSERT INTO {table} VALUES ({var})' .format( table=table_name, var=string) ) 这是可行的,但进一步阅读sqlit

sqlite3还很陌生,所以请在这里耐心听我说

我希望有一个可以传递表名和要更新的值的函数

我最初是这样开始的:

def add_to_table(table_name, string):
    cursor.execute('INSERT INTO {table} VALUES ({var})'
        .format(
            table=table_name,
            var=string)
        )
这是可行的,但进一步阅读sqlite3表明,这是一种非常不安全的方式。但是,使用它们的
语法,我无法传入一个名称来指定变量

我尝试添加一个
来代替表,但这会引发语法错误

cursor.execute('INSERT INTO ? VALUES (?)', ('mytable','"Jello, world!"'))
>> >sqlite3.OperationalError: near "?": syntax error  

sql语句中的
能否安全、动态地传递

问题不在于动态字符串替换本身。它的动态字符串替换为用户提供的字符串,这是一个大问题,因为这会使您面临SQL注入攻击。如果您完全100%确定tablename是您控制的安全字符串,那么将其拼接到SQL查询中是安全的

if some_condition():
   table_name = 'TABLE_A'
else:
   table_name = 'TABLE_B'

cursor.execute('INSERT INTO '+ table_name + 'VALUES (?)', values)

这就是说,像这样使用动态SQL肯定是一种代码味道,因此您应该仔细检查,看看是否可以找到一种没有动态生成的SQL字符串的更简单的替代方法。此外,如果您真的需要动态SQL,那么像SQLAlchemy这样的东西可能有助于确保生成的SQL格式正确。

问题不在于动态字符串替换本身。它的动态字符串替换为用户提供的字符串,这是一个大问题,因为这会使您面临SQL注入攻击。如果您完全100%确定tablename是您控制的安全字符串,那么将其拼接到SQL查询中是安全的

if some_condition():
   table_name = 'TABLE_A'
else:
   table_name = 'TABLE_B'

cursor.execute('INSERT INTO '+ table_name + 'VALUES (?)', values)

这就是说,像这样使用动态SQL肯定是一种代码味道,因此您应该仔细检查,看看是否可以找到一种没有动态生成的SQL字符串的更简单的替代方法。此外,如果您真的想要动态SQL,那么像SQLAlchemy这样的东西可能有助于确保生成的SQL格式正确。

使用字符串操作编写SQL语句是奇怪的,这不仅是因为安全问题,还因为字符串是“哑”对象。使用sqlalchemy核心(您甚至不需要ORM部分)几乎就像使用字符串一样,但是每个片段都会更加智能,并且允许更容易的组合。看一看这本书,了解一下我在说什么

例如,使用sqlsoup时,您的代码如下所示:

db = SQLSoup('sqlite://yourdatabase')
table = getattr(db, tablename)
table.insert(fieldname='value', otherfield=123)
db.commit()

另一个优点:代码独立于数据库-是否要迁移到oracle?更改连接字符串就完成了。

使用字符串操作编写SQL语句很奇怪,这不仅是因为存在安全隐患,还因为字符串是“哑”对象。使用sqlalchemy核心(您甚至不需要ORM部分)几乎就像使用字符串一样,但是每个片段都会更加智能,并且允许更容易的组合。看一看这本书,了解一下我在说什么

例如,使用sqlsoup时,您的代码如下所示:

db = SQLSoup('sqlite://yourdatabase')
table = getattr(db, tablename)
table.insert(fieldname='value', otherfield=123)
db.commit()

另一个优点:代码独立于数据库-是否要迁移到oracle?更改连接字符串,您就完成了。

我……真的看不到这方面的使用案例……我对您的动机感到困惑。通过这样做,您希望实现什么?您应该知道要将数据插入到哪个表中。使用类似sqlalchemy的ORM。您是否可以重构您的数据,以使您拥有(比如)带有类型列的食物表,而不是垃圾邮件表和鸡蛋表?(如果您不知道这个问题的答案,可以发布另一个带有精简模式的问题,并询问如何改进它,从而不需要动态表选择?)通常,当您认为需要这样的动态SQL时,答案是错误的数据模型。但是“通常”并不是“总是”,而且在你必须这样做的少数情况下,字符串格式是唯一的选择。我…真的看不到这方面的使用案例…我对你的动机感到困惑。通过这样做,您希望实现什么?您应该知道要将数据插入到哪个表中。使用类似sqlalchemy的ORM。您是否可以重构您的数据,以使您拥有(比如)带有类型列的食物表,而不是垃圾邮件表和鸡蛋表?(如果您不知道这个问题的答案,可以发布另一个带有精简模式的问题,并询问如何改进它,从而不需要动态表选择?)通常,当您认为需要这样的动态SQL时,答案是错误的数据模型。但“通常”并非“总是”,在极少数情况下,字符串格式是唯一的选择。表名和
值之间缺少空格。(这是字符串格式优于串联的许多原因之一。而且,由于OP在他的问题中使用了
格式
,因此不必担心他不会理解它……)表名和
值之间缺少空格。(这是字符串格式优于串联的众多原因之一。而且,由于OP在他的问题中使用了
格式
,因此他不必担心自己不理解它……)