`TypeError: аргумент 2 должен быть соединением, курсором или None` в Psycopg2
У меня настроен конвейер 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 рамки ошибки внизу этого поста.
Файл настроек связан.
Когда я установил DEBUG=True
все работает нормально. Который может предложить ALLOWED_HOSTS
проблема, но когда я установил ALLOWED_HOSTS
в '*'
с DEBUG=False
-А это еще ошибки?
Что не так с моей настройкой? Это работает в постановке и производстве, но не в обзорах приложений.
1 ответ
Я думаю, что это может быть ошибкой из-за одного из следующих:
psycopg2.extensions.register_type
_connect
CPython
static PyObject *psyco_register_type
static 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)
Видимо, это то, что он делает:
код в моем случае, которые вызывают проблему my_connections.py
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
tldr
# example no work
engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=lambda: 'asdf')
# example work
engine = sqlalchemy.create_engine('postgresql+psycopg2://', creator=lambda: conn)