Psycopg2 中的“类型错误:参数 2 必须是连接、游标或无”

2024-02-11

我设置了一个 Heroku 管道,并且刚刚为其启用了评论应用程序。它使用与我的登台和生产应用程序相同的代码库、相同的设置文件和所有内容。

当审核应用程序启动时,它可以连接到创建的数据库并运行迁移。当我尝试连接到浏览器中的应用程序时,我得到

`TypeError: argument 2 must be a connection, cursor or None` in `psycopg2/_json.py, register_json:139`

堆栈顶部是:

`django.contrib.sites.models._get_site_by_id`.

我在这篇文章的底部附上了错误帧的 Opbeat 输出。

设置文件 https://github.com/phildini/logtacts/blob/master/logtacts/prod_settings/__init__.py已连接。

当我设置DEBUG=True,一切正常。这可能会建议ALLOWED_HOSTS问题,但是当我设置时ALLOWED_HOSTS to '*' with DEBUG=False,仍然错误?

我的设置有什么问题吗?这适用于登台和生产,但不适用于评论应用程序。


tldr

# example borked
engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=lambda: 'asdf')
# example works
engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=lambda: conn)

我认为这可能是以下之一的错误:

  • psycopg2.extensions.register_type

  • _connect

  • cpython

    • static PyObject *psyco_register_type
    • static PyObject * psyco_connect

examples

具体来说,可以从以下位置引发错误:

psycopg2.

_ipaddress.py
_json.py
_psycopg.cpython-37m-darwin.so
_range.py
extensions.py
extras.py

就我而言:

_ext.register_type(_ext.UUID, conn_or_curs)

显然这就是它的作用:

  • https://github.com/psycopg/psycopg2/blob/master/doc/src/extensions.rst#database-types-casting-functions https://github.com/psycopg/psycopg2/blob/master/doc/src/extensions.rst#database-types-casting-functions

在我的例子中导致问题的代码是create_engine关键词creator=get_connection在以下示例中:

 from psycopg2.pool import ThreadedConnectionPool
 from contextlib import contextmanager
 import sqlalchemy
 conn_string = "host='127.0.0.1' dbname='postgres' user='someuser' password='somepassword'"
 top = ThreadedConnectionPool(1, 250, conn_string)

 @contextmanager
 def get_connection():
     try:
         connection = top.getconn()
         yield connection
     finally:
         top.putconn(connection)

 @contextmanager
 def get_cursor(commit=False):
     with get_connection() as connection:
         cursor = connection.cursor(
             cursor_factory=psycopg2.extras.RealDictCursor)
         try:
             yield cursor
             if commit:
                 connection.commit()
         finally:
             cursor.close()

 engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=get_connection)

 @contextmanager
 def get_sqlalchemy_engine():
     yield engine.connect()

导致问题的原因:

with get_sqlalchemy_engine() as engine:
    pd.DataFrame([1]).to_sql('asdf', engine, if_exists='replace')

以及解决问题的方法:

@contextmanager
def get_sqlalchemy_engine():
    with get_connection() as conn:
        try:
            engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=lambda: conn)
            # engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=lambda: 'asdf')
            yield engine
        finally:
            engine.dispose()

进一步的研究表明:

JSON = new_type((oid, ), name, typecast_json)
if array_oid is not None:
    JSONARRAY = new_array_type((array_oid, ), "%sARRAY" % name, JSON)
else:
    JSONARRAY = None

return JSON, JSONARRAY

基本上conn_or_curs不是连接或光标,而是其他东西,

register_type(JSON, not globally and conn_or_curs or None)
register_type(JSONARRAY, not globally and conn_or_curs or None)
  • https://github.com/psycopg/psycopg2/blob/f947c0e6be1d2c3ea8d2d8badf683b95bd213444/psycopg/psycopgmodule.c#L189 https://github.com/psycopg/psycopg2/blob/f947c0e6be1d2c3ea8d2d8badf683b95bd213444/psycopg/psycopgmodule.c#L189
  • https://github.com/psycopg/psycopg2/blob/f947c0e6be1d2c3ea8d2d8badf683b95bd213444/psycopg/psycopgmodule.c#L260 https://github.com/psycopg/psycopg2/blob/f947c0e6be1d2c3ea8d2d8badf683b95bd213444/psycopg/psycopgmodule.c#L260
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Psycopg2 中的“类型错误:参数 2 必须是连接、游标或无” 的相关文章

随机推荐