Psycopg2中的“ TypeError:参数2必须是连接,游标或无” [英] `TypeError: argument 2 must be a connection, cursor or None` in Psycopg2

查看:140
本文介绍了Psycopg2中的“ TypeError:参数2必须是连接,游标或无”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经建立了一个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或无)




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)

这篇关于Psycopg2中的“ TypeError:参数2必须是连接,游标或无”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆