`TypeError: argument 2 must be a connection, cursor or None` 在 Psycopg2
Posted
技术标签:
【中文标题】`TypeError: argument 2 must be a connection, cursor or None` 在 Psycopg2【英文标题】:`TypeError: argument 2 must be a connection, cursor or None` in Psycopg2 【发布时间】:2017-03-09 08:08:51 【问题描述】:我设置了一个 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 输出。
Settings file 已链接。
当我设置DEBUG=True
时,一切正常。这可能表明存在ALLOWED_HOSTS
问题,但是当我将ALLOWED_HOSTS
设置为'*'
和DEBUG=False
时,它仍然会出错吗?
我的设置有什么问题?这适用于暂存和生产,但不适用于评论应用。
【问题讨论】:
phildini,你找到解决这个问题的方法了吗? @Dário 我仍然不知道确切的问题是什么,但升级 psycopg2 软件包解决了它。 【参考方案1】: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
例子
https://github.com/psycopg/psycopg2/search?q=register_type&unscoped_q=register_type具体可以从以下位置引发错误:
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在我的案例中导致问题的代码是以下示例中的 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#L260
【讨论】:
以上是关于`TypeError: argument 2 must be a connection, cursor or None` 在 Psycopg2的主要内容,如果未能解决你的问题,请参考以下文章
`TypeError: argument 2 must be a connection, cursor or None` 在 Psycopg2
Python_异常:TypeError: write() argument must be str, not list
TypeError: Failed to execute ‘setItem‘ on ‘Storage‘: 2 arguments requir
python继承初始化对象实例时 TypeError: module() takes at most 2 arguments (3 given)
TypeError: __sigmoid() takes 1 positional argument but 2 were given
亲测已解决TypeError: __init__() takes 1 positional argument but 2 were given