2010-11-13 68 views
1

以下腳本在UPDATE命令中引發以下異常。我認爲這個簡單的UPDATE命令應該發生的事情是,db_2.foo.bar的值應該從1加倍到2.我的猜測是我在UPDATE語句中有一些細微的語法錯誤(或者Python中的一個錯誤或sqlite3級別);然而,我已經鑽研了sqlite3文檔 - 特別是「UPDATE」和「表達式」頁面 - 並沒有看到我做錯了什麼。Python 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() 

回答

1

要使用不同表格中的值更新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不匹配rowidsdb_2.foo的:

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)''') 

在更新之後,與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,雖然任何錯誤當然是我自己的。

0

嗯......這個問題很可能是我正在查看3.7.3文檔,而我的安裝版本是3.6.16。調查。

+0

這似乎並非如此。雖然我找不到3.6.16文檔,但我有舊的文檔可以追溯到2005年,即使​​根據該文檔,腳本中UPDATE命令的語法也是有效的。 – 2010-11-13 03:33:47

相關問題