Psycopg2中的“ TypeError:参数2必须是连接,游标或无” [英] `TypeError: argument 2 must be a connection, cursor or None` in Psycopg2
问题描述
我已经建立了一个heroku管道,并且刚刚启用了评论应用程序。它使用与我的登台和生产应用程序相同的代码库,相同的设置文件以及所有内容。
当审阅应用程序启动时,它可以连接到创建的数据库并运行迁移。当我尝试连接到浏览器中的应用程序时,我得到
`TypeError:参数2必须是连接,游标或psycopg2 / _json.py,register_json:139`中的None`
堆栈顶部是:
`django.contrib.sites.models._get_site_by_id`。
我在本文的底部附加了错误帧的Opbeat输出。
tldr
#示例让
engine = sqlalchemy.create_engine ('postgresql + psycopg2://',creator = lambda:'asdf')
#示例作品
engine = sqlalchemy.create_engine('postgresql + psycopg2://',creator = lambda:conn)
我认为这可能是以下其中一项的错误:
-
psycopg2.extensions.register_type
-
_connect
-
cpython
-
静态PyObject * psyco_register_type
-
静态PyObject * psyco_connect
-
示例
特别是错误可能来自:
psycopg2。
_ipaddress.py
_json.py
_psycopg.cpython-37m- darwin.so
_range.py
extensions.py
extras.py
在我的情况下:
_ext.register_type(_ext.UUID,conn_or_curs)
显然是这样的:
- < a href = https://github.com/psycopg/psycopg2/blob/master/doc/src/extensions.rst#database-types-casting-functions rel = nofollow noreferrer> https://github.com /psycopg/psycopg2/blob/master/doc/src/extensions.rst#database-types-casting-functions
在我这个案例中,引起问题的代码是 create_engine
关键字 creator = get_connection
在以下示例中:
来自psycopg2.pool从contextlib导入ThreadedConnectionPool
导入contextmanager
导入sqlalchemy
conn_string = host ='127.0.0.1'dbname ='postgres'user ='someuser'password ='somepassword'
top = ThreadedConnectionPool(1,250,conn_string)
@contextmanager
def get_connection():
尝试:
connection = top.getconn()
最终产生连接
:
top.putconn(连接)
@contextmanager
def get_cursor(commit = False):
与get_connection( )作为连接:
游标= connection.cursor(
cursor_factory = psycopg2.extras.RealDictCursor)
尝试:
如果提交:
产生游标
.commit()
最后:
cursor.close()
engine = sqlalchemy.c reate_engine('postgresql + psycopg2://',creator = get_connection)
@contextmanager
def get_sqlalchemy_engine():
yield engine.connect()
导致问题的原因:
以get_sqlalchemy_engine()作为引擎:
pd.DataFrame([1])。to_sql('asdf',engine,if_exists ='replace')
问题解决的原因:
@contextmanager
def get_sqlalchemy_engine():
,其中conn:getbconnection():
尝试:
engine = sqlalchemy.create_engine('postgresql + psycopg2://',creator = lambda:conn)
#engine = sqlalchemy.create_engine('postgresql + psycopg2://',creator = lambda:'asdf')
最终产生的引擎
:
engine.dispose()
进一步的研究表明:
JSON = new_type((oid,),name,typecast_json)
如果array_ oid不是None:
JSONARRAY = new_array_type((array_oid,),%sARRAY%name,JSON)
其他:
JSONARRAY = None
返回JSON ,JSONARRAY
基本上 conn_or_curs
不是连接或游标,而是其他东西,
register_type(JSON,不全局,conn_or_curs或None)
register_type( JSONARRAY,不在全局范围内,并且不是conn_or_curs或无)
- https://github.com/psycopg/psycopg/ybgdbd/bb/fb2df1d2dbdf1dbdffdbdfdbdfbdfdbdfdbdfdbdfdbdfdbdfdfdbdfdbdfdbdfbdfbdfbdfdbdf8d .c#L189
- https://github.com/psycopg/psycopg2/blob/f947c0e6be1d2c3ea8d2d8badf683b95bd213444/p sycopg / psycopgmodule.c#L260
I have a heroku pipeline set up, and have just enabled review apps for it. It is using the same codebase as my staging and production apps, same settings files and everything.
When the review app spins up, it can connect to the created DB and run migrations. When I try to connect to the app in the browser, I get
`TypeError: argument 2 must be a connection, cursor or None` in `psycopg2/_json.py, register_json:139`
Top of stack is:
`django.contrib.sites.models._get_site_by_id`.
I've attached the Opbeat output of the error frame at the bottom of this post.
Settings file is linked.
When I set DEBUG=True
, everything works fine. Which might suggest an ALLOWED_HOSTS
issue, but when I set ALLOWED_HOSTS
to '*'
with DEBUG=False
, it still errors?
What is wrong with my setup? This works in staging, and production, but not the review apps.
tldr
# example borked
engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=lambda: 'asdf')
# example works
engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=lambda: conn)
I think this might be an error from one of the following:
psycopg2.extensions.register_type
_connect
cpython
static PyObject *psyco_register_type
static PyObject * psyco_connect
examples
Specifcally the error can be raised from :
psycopg2.
_ipaddress.py
_json.py
_psycopg.cpython-37m-darwin.so
_range.py
extensions.py
extras.py
in my case:
_ext.register_type(_ext.UUID, conn_or_curs)
Apparently this is what it does:
the code in my case which caused the issue was the create_engine
keyword creator=get_connection
in the following example:
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()
what caused the issue:
with get_sqlalchemy_engine() as engine:
pd.DataFrame([1]).to_sql('asdf', engine, if_exists='replace')
And what fixed the issue:
@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()
further research indicates the following:
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
basically conn_or_curs
is not a connection or cursor, but rather some other thing,
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
这篇关于Psycopg2中的“ TypeError:参数2必须是连接,游标或无”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!