1

eは私のエンジンであり、通常の選択、挿入などを実行できますが、「選択または無視」タイプの質問を実行したい場合、奇妙な動作が発生します。

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)はそのテーブルにありません。テーブルを最初から再作成しても、同じ結果が得られます。

4

1 に答える 1

1

最近の SQLA バージョンでは再現できません。SQLA のバージョンは? pg8000のバージョンは?pg8000 を最新のものにアップグレードできるかどうかを確認してください。実際にはアクティブなプロジェクトではありません。psycopg2 は、一般的な使用に非常に適しています。

from sqlalchemy import create_engine
e = create_engine("postgresql+pg8000://scott:tiger@localhost/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
于 2012-12-07T14:50:05.873 に答える