使用SQLite插入命令解决“无法识别的令牌”错误

时间:2019-07-13 08:29:52

标签: python pandas sqlite

我不断收到OperationalError:无法识别的令牌。当我尝试使用SQLite插入命令将数据插入我的SQLite数据库时,会出现该错误。我需要做些什么来纠正此错误,或者是否应该有更好的方法将数据插入数据库?数据是在图表数据上方以米为单位测量的水位数据,是从加拿大和美国大湖地区的水位计数据记录器收集的。该脚本使用了Pandas库,并进行了硬编码以合并来自彼此紧邻的水位测量站的数据。我想使用insert命令,以便在将将来的数据添加到数据库时可以处理重叠的数据。我什至不会假装我知道我在谈论数据库和编程,因此我将在解决该错误方面为您提供任何帮助!

我曾尝试更改参数化查询中的脚本以尝试解决问题而没有任何运气,因为我的研究表明这可能是罪魁祸首

    # Tecumseh. Merges station in steps due to inability of operation to merge all stations at once. Starts by merging PCWL station to hydromet station followed by remaining PCWL station and 3 minute time series
    final11975 = pd.merge(hydrometDF["Station11975"], pcwlDF["station11995"], how='outer', left_index=True,right_index=True)
    final11975 = pd.merge(final11975, pcwlDF["station11965"], how='outer', left_index=True,right_index=True)
    final11975 = pd.merge(final11975, cts, how='outer', left_index=True,right_index=True)
final11975.to_excel("C:/Users/Andrew/Documents/CHS/SeasonalGaugeAnalysis_v2/SeasonalGaugeAnalysis/Output/11975_Tecumseh.xlsx")
    print "-------------------------------"
    print "11975 - Tecumseh"
    print(final11975.info())
    final11975.index = final11975.index.astype(str)
    #final11975.to_sql('11975_Tecumseh', conn, if_exists='replace', index=True)
    #Insert and Ignore data into database to eliminate overlaps
        testvalues = (final11975.index, final11975.iloc[:,0], final11975.iloc[:,1], final11975.iloc[:,2])
        c.execute("INSERT OR IGNORE INTO 11975_Tecumseh(index,11975_VegaRadar(m),11995.11965), testvalues")
        conn.commit()

我希望使用“插入并忽略”命令将数据插入数据库,因为下载时数据经常重叠。我是数据库新手,但给人一种“插入并忽略”命令将消除重叠数据的印象。运行脚本时收到的消息是:

</> <Exception has occurred: OperationalError
unrecognized token: "11975_Tecumseh"
  File "C:\Users\Documents\CHS\SeasonalGaugeAnalysis_v2\SeasonalGaugeAnalysis\Script\CombineStations.py", line 43, in <module>>
    c.execute("INSERT OR IGNORE INTO 11975_Tecumseh(index,11975_VegaRadar(m),11995.11965), testvalues") </>

2 个答案:

答案 0 :(得分:1)

您遇到的错误是因为表名 11975_Tecumseh 无效,因为它没有适当地封闭。

  

如果要使用关键字作为名称,则需要引用它。那里   SQLite中引用关键字的四种方法:

     
      
  • “关键字”单引号中的关键字是字符串文字。
  •   
  • “关键字”用双引号引起来的关键字是一个标识符。 [关键字] A
  •   用方括号括起来的
  • 关键字是一个标识符。      
        
    • 这不是   标准SQL。 MS Access和SQL使用此报价机制   服务器,并包含在SQLite中以实现兼容性。 keyword A
    •   
  •   带有重音符号(ASCII码96)的
  • 关键字是一个标识符。      
        
    • 这不是标准的SQL。这种报价机制由MySQL和   为了兼容性,包含在SQLite中。为了增强弹性   面对历史上的SQL语句,SQLite有时会弯曲   上面的报价规则:
    •   
  •   
     

如果在单引号中使用单引号引起来的关键字(例如:“ key”或“ glob”)   允许标识符但字符串文字是上下文的上下文   不允许,则将令牌理解为标识符   字符串文字。

     

如果在关键字中使用双引号引起来的关键字(例如:“ key”或“ glob”)   无法解析为标识符的上下文,但是   允许使用字符串文字,那么令牌将被理解为字符串   文字而不是标识符。

     

警告程序员不要使用以下描述的两个例外   以前的项目符号。我们强调,它们的存在仅是为了   并且格式错误的SQL语句将正确运行。的未来版本   SQLite可能会引发错误,而不是接受格式错误的错误   上述例外情况所涵盖的声明。

SQL As Understood By SQLite - SQLite Keywords -以上内容适用于无效名称,包括以数字开头的名称,在括号内包含非数字的名称。

如果 11975_Tecumseh 是实际的表名,则必须将其括起来,例如 [11975_Tecumseh]

与列类似

  • 索引
  • 11975_VegaRadar(m)
  • 11995.11965

还必须适当封闭。

这样做最终会导致

"INSERT OR IGNORE INTO [11975_Tecumseh]([index],[11975_VegaRadar(m)],[11995.11965]), testvalues"

问题在于,testvalues在语法上不正确。在要插入([index],[11975_VegaRadar(m)],[11995.11965])的列之后,应使用带有三个值的关键字VALUES。

有效语句的一个示例是:-

"INSERT INTO [11975_Tecumseh] ([index],[11975_VegaRadar(m)],[11995.11965]) VALUES('value1','value2','value3')"

就这样

c.execute("INSERT INTO [11975_Tecumseh] ([index],[11975_VegaRadar(m)],[11995.11965]) VALUES('value1','value2','value3')")

将插入新行(除非发生约束冲突

但是,我怀疑您想根据变量插入值,在这种情况下可以使用。

"INSERT INTO [11975_Tecumseh] ([index],[11975_VegaRadar(m)],[11995.11965]) VALUES(?,?,?)"

然后将使用:-

调用以上内容
c.execute("INSERT INTO [11975_Tecumseh] ([index],[11975_VegaRadar(m)],[11995.11965]) VALUES(?,?,?)",testvalues);

工作示例:-

import sqlite3
drop_sql = "DROP TABLE IF EXISTS [11975_Tecumseh]"
crt_sql = "CREATE TABLE IF NOT EXISTS [11975_Tecumseh] ([index],[11975_VegaRadar(m)],[11995.11965])"
testvalues = ("X","Y","Z")

c = sqlite3.connect("test.db")
c.execute(drop_sql)
c.execute(crt_sql)

insert_sql1 = "INSERT INTO [11975_Tecumseh] " \
              "([index],[11975_VegaRadar(m)],[11995.11965]) " \
              "VALUES('value1','value2','value3')"
c.execute(insert_sql1)

insert_sql2 = "INSERT OR IGNORE INTO '11975_Tecumseh'" \
              "('index','11975_VegaRadar(m)',[11995.11965])" \
              " VALUES(?,?,?)"

c.execute(insert_sql2,(testvalues))
cursor = c.cursor()
cursor.execute("SELECT * FROM [11975_Tecumseh]")
for row in cursor:
    print(row[0], "\n" + row[1], "\n" + row[2])
c.commit()
cursor.close()
c.close()

结果

第1行

value1 
value2 
value3

第2行

X 
Y 
Z

答案 1 :(得分:0)

根据SQL标准,您可以创建表或列名,例如“ 11975_Tecumseh”,也可以创建Tecumseh_11975,但是如果不使用双引号,则不能创建以数字开头的表或列名。

c.execute("INSERT OR IGNORE INTO '11975_Tecumseh'(index,'11975_VegaRadar(m)',11995.11965), testvalues")