Being that string substitution is frowned upon with forming SQL queries, how do you assign the table name dynamically?
sqlite3相当新,所以在这里忍受..
我希望有一个函数,我可以将表名和值传递给该函数。
我最初是这样的:
1 2 3 4 5 6 | def add_to_table(table_name, string): cursor.execute('INSERT INTO {table} VALUES ({var})' .format( table=table_name, var=string) ) |
哪个工作还可以,但是对sqlite3的进一步阅读表明这是处理事情的一种非常不安全的方法。但是,使用他们的
我尝试添加
1 2 | cursor.execute('INSERT INTO ? VALUES (?)', ('mytable','"Jello, world!"')) >> >sqlite3.OperationalError: near"?": syntax error |
是否可以安全,动态地传递sql语句中的
不是动态字符串替换本身就是问题所在。用用户提供的字符串动态替换字符串是个大问题,因为这使您容易受到SQL注入攻击。如果您完全100%确定表名是您控制的安全字符串,那么将其拼接到SQL查询中将是安全的。
1 2 3 4 5 6 | 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部分)几乎就像使用字符串一样,但是每个片段都将更加智能,并且可以更轻松地进行编写。看看sqlalchemy Wiki,以了解我在说什么。
例如,使用sqlsoup,您的代码将如下所示:
1 2 3 4 | db = SQLSoup('sqlite://yourdatabase') table = getattr(db, tablename) table.insert(fieldname='value', otherfield=123) db.commit() |
另一个优势:代码与数据库无关-想要迁移到oracle吗?更改连接字符串即可完成。