2012-12-05 40 views
1

e是我的引擎,我可以做定期選擇,插入等等,但是當我想要做一個「選擇或忽略」類型questy,我得到一個奇怪的行爲:sqlachemy奇怪的行爲與%s在選擇

e.execute('insert into users (username) select %s where not exists (select 1 from users where username = %s);', 'toto', 'toto') 

我得到:

Traceback (most recent call last): 
    File "/usr/lib/python3/dist-packages/sqlalchemy/engine/base.py", line 1416, in _cursor_executemany 
    context) 
    File "/usr/lib/python3/dist-packages/sqlalchemy/engine/default.py", line 298, in do_executemany 
    cursor.executemany(statement, parameters) 
    File "/projects/bin/packages/pg8000/dbapi.py", line 243, in _fn 
    return fn(self, *args, **kwargs) 
    File "/projects/bin/packages/pg8000/dbapi.py", line 370, in executemany 
    self._execute(operation, parameters) 
    File "/projects/bin/packages/pg8000/dbapi.py", line 319, in _execute 
    self.cursor.execute(new_query, *new_args) 
    File "/projects/bin/packages/pg8000/interface.py", line 301, in execute 
    self._stmt.execute(*args, **kwargs) 
    File "/projects/bin/packages/pg8000/interface.py", line 136, in execute 
    self._row_desc, cmd = self.c.bind(self._portal_name, self._statement_name, args, self._parse_row_desc, kwargs.get("stream")) 
    File "/projects/bin/packages/pg8000/protocol.py", line 933, in _fn 
    return fn(self, *args, **kwargs) 
    File "/projects/bin/packages/pg8000/protocol.py", line 1116, in bind 
    return reader.handle_messages() 
    File "/projects/bin/packages/pg8000/protocol.py", line 901, in handle_messages 
    retval = handler(msg, *args, **kwargs) 
    File "/projects/bin/packages/pg8000/protocol.py", line 1155, in _bind_nodata 
    reader.handle_messages() 
    File "/projects/bin/packages/pg8000/protocol.py", line 906, in handle_messages 
    raise exc 
pg8000.errors.ProgrammingError: (b'ERROR', b'23505', b'duplicate key value violates unique constraint "users_pkey"') 

The above exception was the direct cause of the following exception: 

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python3/dist-packages/sqlalchemy/engine/base.py", line 1790, in execute 
    return connection.execute(statement, *multiparams, **params) 
    File "/usr/lib/python3/dist-packages/sqlalchemy/engine/base.py", line 1191, in execute 
    params) 
    File "/usr/lib/python3/dist-packages/sqlalchemy/engine/base.py", line 1287, in _execute_text 
    return self.__execute_context(context) 
    File "/usr/lib/python3/dist-packages/sqlalchemy/engine/base.py", line 1297, in __execute_context 
    context.parameters, context=context) 
    File "/usr/lib/python3/dist-packages/sqlalchemy/engine/base.py", line 1423, in _cursor_executemany 
    context) 
    File "/usr/lib/python3/dist-packages/sqlalchemy/engine/base.py", line 1360, in _handle_dbapi_exception 
    from e 
sqlalchemy.exc.ProgrammingError: (ProgrammingError) (b'ERROR', b'23505', b'duplicate key value violates unique constraint "users_pkey"') 'insert into users (username) select %s where not exists (select 1 from users where username = %s);' [('x', 'o', 'x', 'o'), ('x', 'o', 'x', 'o')] 

該數值(XOXO)是不是在該表中,我得到同樣的事情,甚至從頭開始的時候重新創建表。

+1

我覺得很奇怪的是'xoxo'被記入'( 'X', 'O', 'X', 'O'),'。你的桌子有價值''''嗎?如果是的話,這可能是失敗的原因。也許你可以嘗試發出'e.execute('insert into users(username)select%s where not exists(從用戶名中選擇1,其中用戶名=%s);',''toto',),''toto', ))'而不是。但是,理想情況下,您應該使用['sqlalchemy.sql.expression.text'](http://docs.sqlalchemy.org/en/rel_0_8/core/expression_api.html#sqlalchemy.sql.expression.text)結構。 – van

回答

1

無法用最近的SQLA版本重現。什麼SQLA版本?什麼pg8000版本?看看你是否可以將pg8000升級到最新版本,這不是一個真正的活躍項目。 psycopg2是一般用途的首選。

from sqlalchemy import create_engine 
e = create_engine("postgresql+pg8000://scott:[email protected]/test", echo=True) 

c = e.connect() 
t = c.begin() 
c.execute("create table users (username varchar(50) primary key)") 

for i in range(10): 
    c.execute('insert into users (username) select %s where not exists ' 
     '(select 1 from users where username = %s);', 'toto', 'toto') 

t.rollback() 

輸出:

2012-12-07 09:48:15,381 INFO sqlalchemy.engine.base.Engine select current_schema() 
2012-12-07 09:48:15,382 INFO sqlalchemy.engine.base.Engine() 
2012-12-07 09:48:15,387 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 
2012-12-07 09:48:15,387 INFO sqlalchemy.engine.base.Engine create table users (username varchar(50) primary key) 
2012-12-07 09:48:15,387 INFO sqlalchemy.engine.base.Engine() 
2012-12-07 09:48:15,413 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,413 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,422 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,422 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,424 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,424 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,426 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,426 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,427 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,427 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,428 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,428 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,429 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,429 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,431 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,431 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,432 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,432 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,433 INFO sqlalchemy.engine.base.Engine insert into users (username) select %s where not exists (select 1 from users where username = %s); 
2012-12-07 09:48:15,433 INFO sqlalchemy.engine.base.Engine ('toto', 'toto') 
2012-12-07 09:48:15,434 INFO sqlalchemy.engine.base.Engine ROLLBACK