在Python循环中将列添加到SQLite表

det*_*tox 0 python sqlite

我为科学程序(Python)创建了一个数据库(使用sqlite3)。该程序的建立使循环逐渐建立数据库。因此,问题在于添加带有循环的列。我举了一个例子。它表明问题出在定义新列名(Name1)的变量上。

import sqlite3
import os

conn=sqlite3.connect(':memory:')
c=conn.cursor()

c.execute('''CREATE TABLE TableName (Var1 REAL, Var2 REAL)''')

Name1='Test1'
c.execute('''ALTER TABLE TableName ADD COLUMN "+Name1+" INTEGER''')
Name1='Test2'
c.execute('''ALTER TABLE TableName ADD COLUMN "+Name1+" INTEGER''')
Run Code Online (Sandbox Code Playgroud)

请问有人可以解决这个问题吗?感谢,并有一个愉快的一天。

das*_*s-g 6

字符串文字必须以与它们相同的引号终止。因此,会"+Name1+"被解释为字符串的文字部分,并在c.execute(...)Name1插入变量的情况下传递给。

因此,两个新列都将具有文字名称+Name1+,这将导致错误消息

sqlite3.OperationalError: duplicate column name: +Name1+
Run Code Online (Sandbox Code Playgroud)

您可能想要类似的东西:

import sqlite3

conn = sqlite3.connect(':memory:')
c = conn.cursor()

c.execute('''CREATE TABLE TableName (Var1 REAL, Var2 REAL)''')

name1 = 'Test1'
c.execute('''ALTER TABLE TableName ADD COLUMN ''' + name1 + ''' INTEGER''')
name1 = 'Test2'
c.execute('''ALTER TABLE TableName ADD COLUMN ''' + name1 + ''' INTEGER''')
Run Code Online (Sandbox Code Playgroud)

用循环重写,那将是

import sqlite3

conn = sqlite3.connect(':memory:')
c = conn.cursor()

c.execute('''CREATE TABLE TableName (Var1 REAL, Var2 REAL)''')

for column_name in ['Test1', 'Test2']:
    c.execute('''ALTER TABLE TableName ADD COLUMN ''' + column_name + ''' INTEGER''')
Run Code Online (Sandbox Code Playgroud)

为了避免SQL注入的风险,尽管如此,您不应在SQL查询或命令上进行字符串连接或操作。取而代之的是使用参数替换Python的数据库API已提供:

import sqlite3

conn = sqlite3.connect(':memory:')
c = conn.cursor()

c.execute('''CREATE TABLE TableName (Var1 REAL, Var2 REAL)''')

for column_name in ['Test1', 'Test2']:
    c.execute('''ALTER TABLE TableName ADD COLUMN ? INTEGER''', (column_name,))
Run Code Online (Sandbox Code Playgroud)

实际上,API将使不必要显式循环

import sqlite3

conn = sqlite3.connect(':memory:')
c = conn.cursor()

c.execute('''CREATE TABLE TableName (Var1 REAL, Var2 REAL)''')

column_names = [('Test1',), ('Test2',)]:
c.executemany('''ALTER TABLE TableName ADD COLUMN ? INTEGER''', column_names)
Run Code Online (Sandbox Code Playgroud)