Python sqlite3 : UPDATE failure claims "no such column"

标签 python sqlite

以下脚本在 UPDATE 命令中引发以下异常。我认为这个简单的 UPDATE 命令应该发生的是 db_2.foo.bar 的值应该从 1 加倍到 2。我的猜测是我在 UPDATE 语句中有一些微妙的语法错误(或者是 Python 中的错误)或sqlite3级别);然而,我仔细研究了 sqlite3 文档——尤其是“更新”和“表达式”页面——并没有发现我做错了什么。

db_1.foo_bar= (1,)
Traceback (most recent call last):
  File "try2.py", line 29, in <module>
    db_2.execute( 'UPDATE foo SET bar = bar + db_1.foo.bar WHERE rowid = db_1.foo.rowid' ) 
sqlite3.OperationalError: no such column: db_1.foo.bar

有什么建议或解决方法吗?

import sqlite3

# Create db_1, populate it and close it:
open( 'db_1.sqlite', 'w+' )
db_1 =  sqlite3.connect( 'db_1.sqlite' )
db_1.execute( 'CREATE TABLE foo(bar INTEGER)' )
db_1.execute( 'INSERT INTO foo (bar) VALUES (1)' )
db_1.commit()
db_1.close()

# Create db_2:
open( 'db_2.sqlite', 'w+' )
db_2 =  sqlite3.connect( 'db_2.sqlite' )
db_2.execute( 'CREATE TABLE foo(bar INTEGER)' )

# Attach db_1 to db_2 connection:
db_2.execute( 'ATTACH "db_1.sqlite" AS db_1' )

# Populate db_2 from db_1:
db_2.execute( 'INSERT INTO foo SELECT ALL * FROM db_1.foo' )

# Show that db_1.foo.bar exists:
cur_2 = db_2.cursor()
cur_2.execute( 'SELECT bar from db_1.foo' )
for result in cur_2.fetchall():
    print 'db_1.foo_bar=', result

# However, the following claims that db_1.foo.bar does not exist:
db_2.execute( 'UPDATE foo SET bar = bar + db_1.foo.bar WHERE rowid = db_1.foo.rowid' ) 

db_2.execute( 'DETACH db_1')
db_2.commit()
db_2.close()

最佳答案

要使用不同表中的值更新 foo,您可以使用嵌套 SELECT 表达式。注意,foo.rowid指的是外表的rowid,而t.rowid指的是内表的rowid:

cur_2.execute( '''\
    UPDATE foo SET bar = bar +
        IFNULL( (SELECT t.bar 
                 FROM db_1.foo AS t
                 WHERE foo.rowid = t.rowid), 0)''' )  

为了测试正确的 rowids 确实匹配在一起,我稍微修改了您的代码,以便 db_1.foorowids 执行此操作与 db_2.foorowids 不匹配:

import sqlite3

# Create db_1, populate it and close it:
open( 'db_1.sqlite', 'w+' )
db_1 =  sqlite3.connect( 'db_1.sqlite' )
db_1.execute( 'CREATE TABLE foo(bar INTEGER)' )
db_1.execute( 'INSERT INTO foo (rowid,bar) VALUES (2,1)' )
db_1.execute( 'INSERT INTO foo (rowid,bar) VALUES (3,2)' )
db_1.commit()
db_1.close()

# Create db_2:
open( 'db_2.sqlite', 'w+' )
db_2 =  sqlite3.connect( 'db_2.sqlite' )
cur_2 = db_2.cursor()
cur_2.execute( 'CREATE TABLE foo(bar INTEGER)' )

# Attach db_1 to db_2 connection:
cur_2.execute( 'ATTACH "db_1.sqlite" AS db_1' )

# Populate db_2 from db_1:
cur_2.execute( 'INSERT INTO foo SELECT * FROM db_1.foo' )

注意 foorowids 是 1 和 2:

cur_2.execute( 'SELECT rowid,bar from foo' )
for result in cur_2.fetchall():
    print('foo: {0}'.format(result))
    # foo: (1, 1)
    # foo: (2, 2)

请注意 db_1.foorowids 是 2 和 3:

# Show that db_1.foo.bar exists:
cur_2.execute( 'SELECT rowid,bar from db_1.foo' )
for result in cur_2.fetchall():
    print('db_1.foo: {0}'.format(result))
    # db_1.foo: (2, 1)
    # db_1.foo: (3, 2)

cur_2.execute( '''\
    UPDATE foo SET bar = bar +
        IFNULL( (SELECT t.bar 
                 FROM db_1.foo AS t
                 WHERE foo.rowid = t.rowid), 0)''' )  

UPDATE后,rowid = 1的行没有改变, 而 rowid = 2 的行已更新。

cur_2.execute( 'SELECT rowid,bar from foo' )
for result in cur_2.fetchall():
    print('foo after update: {0} '.format(result))
    # foo after update: (1, 1) 
    # foo after update: (2, 3) 

cur_2.execute('DETACH db_1')
db_2.commit()
db_2.close()

我发现这些页面有助于构建这个答案:herehere ,尽管任何错误当然都是我自己的。

关于Python sqlite3 : UPDATE failure claims "no such column",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4170171/

相关文章:

python - 检查具有 OneToOneField 的对象是新的还是已经存在

python - 选择要从 Excel 读入 pandas 数据框的行号

android - java.sql.SQLException : Unable to run insert stmt on object 异常

android - 如何仅根据该记录的部分匹配返回记录?

c# - 如何躲避sqlite中已经存在的表

android - ToggleButtons 的 SQLite Dynamic where-clause

Python - 从旧式类继承

python - 将数据框从宽变为长并应用 map (Python 3.5.1 Pandas)

python - 找不到sqlite3数据库在哪里

iphone - 如何根据 objective-c 中的当前位置找到最近的100米经纬度,Iphone