Python sqlite3,借助.format

时间:2019-02-25 16:44:24

标签: python-3.x sqlite

我正在尝试自动创建一个很大的sqlite数据库表,这些表都至少有50列。列名已在其他列表中提供。 使用.format我几乎做到了。唯一未解决的问题是从名称列表的长度中预先确定“ {}”的占位符数量。请参见下面的代码示例。

import sqlite3

db_path = "//Some path/"
sqlite_file = 'index_db.sqlite'

conn = sqlite3.connect(db_path + sqlite_file)
c = conn.cursor()

db_columns=['c1','c2','c3','c4','c5']

#This code is working
c.execute("create table my_table1 ({}, {}, {}, {}, {})" .format(*db_columns))
#This code doesn't work
c.execute("create table my_table2 (" + ("{}, " * 5)[:-2] + ")" .format(*db_columns))
#Following error appears
OperationalError: unrecognized token: "{"

#--> This even that the curly brackets are the same as in my_table1 
print("create table my_table2 (" + ("{}, " * 5)[:-2] + ")") 
#Output: create table my_table2 ({}, {}, {}, {}, {})

c.execute("INSERT INTO my_table1 VALUES (?,?,?,?,?)", (11, 111, 111, 1111, 11111))

conn.commit()
c.close
conn.close()

是否可以解决my_table2的问题? 还是有更好的方法从列表动态创建列名?

P.s。这是一个内部数据库,由于动态使用变量作为名称,因此我对安全性没有任何担心。

提前谢谢! 铁木尔

1 个答案:

答案 0 :(得分:0)

免责声明

不要使用字符串连接来构建SQL字符串-请参见f.e. http://bobby-tables.com/python了解如何通过参数化查询避免注入。


根据此旧帖子:Variable table name in sqlite,您不能使用“常规”参数化查询来创建表/列名。

您可以通过以下方式预先格式化您的createstatement:

def scrub(table_name):
    # attributation: https://stackoverflow.com/a/3247553/7505395
    return ''.join( chr for chr in table_name if chr.isalnum() )

def createCreateStatement(tableName, columns):
    return f"create table {scrub(tableName)} ({columns[0]}" + (
            ",{} "*(len(columns)-1)).format(*map(scrub,columns[1:])) + ")"

tabName = "demo"
colNames = ["one", "two", "three", "dont do this"]

print(createCreateStatement(tabName, colNames))

输出:

create table demo (one,two ,three ,dontdothis )

scrub方法取自Donald Miner's answer-如果愿意,请投票给他:)