【问题标题】:SQLAlchemy ProgrammingError when inserting into postgresql 11 table插入 postgresql 11 表时出现 SQLAlchemy ProgrammingError
【发布时间】:2020-02-09 08:36:02
【问题描述】:

我无法使用 SQLAlchemy (v1.3.10) 将数据插入到 postgresql 11 表中。我在运行一些以前使用 SQLAlchemy (v1.2.10) 和 posgresql 11 的旧代码时首先注意到了这个错误。我前段时间在我的项目中更新了这两个版本,但直到现在才测试我的代码库的数据库部分(我的错)。代码库相对较大,所以不幸的是,我不确定还有什么可能会导致这个问题。我尝试将 sqlalchemy 和 psycopg2 降级到以前的版本,但这并没有解决问题。不幸的是,恢复到 postgresql 10 更具挑战性,所以我想尽可能避免这种情况。

在尝试插入 ORM 模型对象时首先发生错误,但在尝试使用表达式 API 甚至使用原始 sql 语句插入时,我得到了同样的错误。我设置了一个非常简单的表:

create table test_table(
  id integer not null primary key;
);

并使用带有上下文管理器的Getting a Session 配方创建了一个会话(页面下方)。执行此代码时:

stmt = text("insert into nba.test_table(id) values (:id)")
values = {'id': 3}
session.execute(stmt, values)

我得到以下堆栈跟踪:

Traceback (most recent call last):
  File "/usr/lib64/python3.6/unittest/case.py", line 59, in testPartExecutor
    yield
  File "/usr/lib64/python3.6/unittest/case.py", line 605, in run
    testMethod()
  File "/home/reid/git/worthy/test/test_db.py", line 32, in test_insert
    session.execute(stmt, values)
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 1269, in execute
    clause, params or {}
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 988, in execute
    return meth(self, multiparams, params)
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/sql/elements.py", line 287, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1107, in _execute_clauseelement
    distilled_params,
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1253, in _execute_context
    e, statement, parameters, cursor, context
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1473, in _handle_dbapi_exception
    util.raise_from_cause(sqlalchemy_exception, exc_info)
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/util/compat.py", line 398, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/util/compat.py", line 152, in reraise
    raise value.with_traceback(tb)
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1249, in _execute_context
    cursor, statement, parameters, context
  File "/home/reid/git/worthy/.venv/lib64/python3.6/site-packages/sqlalchemy/engine/default.py", line 580, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near "insert"
LINE 1: ...ECLARE "c_7fbd3ae7c8d0_1" CURSOR WITHOUT HOLD FOR insert int...
                                                             ^

[SQL: insert into nba.test_table(id) values (%(id)s)]
[parameters: {'id': 3}]
(Background on this error at: http://sqlalche.me/e/f405)

无论我使用原始 sql 查询、使用 sqlalchemy 表达式 api 构建的查询还是使用 ORM api 映射的模型类,堆栈跟踪几乎相同。

我可以很好地查询表,如果我直接使用 psycopg2 模块运行等效查询,插入数据也没有问题。

【问题讨论】:

    标签: postgresql sqlalchemy


    【解决方案1】:

    我创建引擎的方式与上面链接中提供的方法略有不同。

    链接如下:

    some_engine = create_engine('postgresql://scott:tiger@localhost/')
    

    因为我已经包含了一个额外的参数

    some_engine = create_engine('postgresql://scott:tiger@localhost/', execution_options={'stream_results': True})
    

    删除 execution_options 参数后,一切都恢复正常。

    【讨论】:

      【解决方案2】:

      connection().execute(...) 用于抓取查询数据。对于其他一切,请尝试让光标运行您的 db 命令。

      这是一个有效的例子:

      conn = create_engine('your_connection_string',
                           execution_options={'stream_results': True}).raw_connection()
      cur = conn.cursor()
      cur.execute(f'SET search_path = public, {other_search_path}')
      
      dfs = []
      for chunk in pd.read_sql(f'''
          SELECT *
          FROM table
          WHERE unique_id = 7777
          ''', conn, chunksize=1000000):
      
          dfs.append(chunk)
      
      return pd.concat(dfs)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-27
        • 1970-01-01
        • 1970-01-01
        • 2019-09-15
        • 2018-06-19
        • 1970-01-01
        相关资源
        最近更新 更多