Python sqlite3: ошибка UPDATE утверждает, что «такой столбец отсутствует» - PullRequest
1 голос
/ 13 ноября 2010

Следующий скрипт вызывает следующее исключение в команде 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()

Ответы [ 2 ]

1 голос
/ 13 ноября 2010

Чтобы обновить 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 действительно сопоставляются, я немного изменил ваш код, чтобы rowids из db_1.foo не совпадало с rowids из db_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' )

Обратите внимание, что rowids из foo равны 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)

Обратите внимание, что rowids из db_1.foo равны 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()

Я нашел эти страницы полезными при построении этого ответа: здесь и здесь , хотя любые ошибки, конечно, мои собственные.

0 голосов
/ 13 ноября 2010

Хммм ... проблема вполне может заключаться в том, что я смотрю документацию 3.7.3, тогда как моя установленная версия - 3.6.16. Исследуя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...