create db.connection custom class wrapper, keep getting "django.db.utils.InterfaceError: cursor already closed"
create db.connection custom class wrapper, keep getting "django.db.utils.InterfaceError: cursor already closed"
我正在尝试为 "django.db.connection" 制作自定义 class 包装器,
但我一直在收到 "django.db.utils.InterfaceError: cursor already closed".
如果没有自定义 class 包装器(从 ./manage.py shell
复制),工作代码是这样的:
>>> from django.db import (connection as con)
>>> with con.cursor() as q:
... q.execute('select * from master.years a where a.years = %s', [str(2019)])
... f = [f.name for f in q.description]
... for b in q:
... print(dict(zip(f,b)))
我的包装器 webapp/mine/db.py
:
class query_00:
def __init__(self, db_con, db_sql, db_stmt = []):
self.db_con = db_con
self.db_sql = db_sql
self.fields = []
with db_con.cursor() as self.query:
self.query.execute(db_sql, db_stmt)
self.fields = [f.name for f in self.query.description]
# for entry in self.query:
# yield dict(zip(self.fields, entry))
# self.query = db_con.cursor()
# must return self, because
# AttributeError: 'NoneType' object has no attribute 'result'
def __enter__(self):
return self
# self.query.execute(self.db_sql, self.db_stmt)
# self.fields = [f.name for f in self.query.description]
# pass
def __exit__(self, exc_type, exc_value, traceback):
# is this necessary?
# self.db_con.close()
pass
def result(self):
for entry in self.query.fetchall():
yield dict(zip(self.fields, entry))
# not working
# for entry in self.query:
# yield dict(zip(self.fields, entry))
# not working
# yield dict(zip(self.fields, entry))
# pass
然后我在./manage.py shell
上输入
试试看
from django.db import (connection as con)
from mine.db import query_00
# expected usage, attempt 1
q = query_00(con, 'SELECT * FROM master.years a where a.year = %s', [str(2019),])
for b in q.result():
print(b)
# expected usage, attempt 2
with query_00(con, 'SELECT * FROM master.years a where a.year = %s', [str(2019),]) as q:
for b in q.result():
print(b)
python-3,django-2,postgresql-9
(对不起我的英文)
所以,在阅读文档后,我意识到连接在我的 init 方法中关闭了。
class query_00:
def __init__(self, db_con, db_sql, db_stmt = []):
self.db_con = db_con
self.db_sql = db_sql
self.fields = []
with db_con.cursor() as self.query:
self.query.execute(db_sql, db_stmt)
self.fields = [f.name for f in self.query.description]
# the connection only happend inside "with:" block
# the connection, was already closed here (after with:)
所以,我只需要将 cursor() 保持在一个变量上
class query_01:
def __init__(self, db_sql, db_stmt):
self.db_sql = db_sql
self.db_stmt = db_stmt
self.query = connection.cursor()
...
将query.execute()
放在另一个方法上
...
def execute(self):
self.query.execute(self.db_sql, self.db_stmt)
self.fields = [f.name for f in self.query.description]
...
结果()
...
def result(self):
self.execute()
for entry in self.query:
yield self.keyvalue(entry)
...
那么我的 class 正在工作
with query_00('SELECT * FROM master.years a where a.year = %s', [str(2019),]) as q:
for b in q.result():
print(b)
我正在尝试为 "django.db.connection" 制作自定义 class 包装器, 但我一直在收到 "django.db.utils.InterfaceError: cursor already closed".
如果没有自定义 class 包装器(从 ./manage.py shell
复制),工作代码是这样的:
>>> from django.db import (connection as con)
>>> with con.cursor() as q:
... q.execute('select * from master.years a where a.years = %s', [str(2019)])
... f = [f.name for f in q.description]
... for b in q:
... print(dict(zip(f,b)))
我的包装器 webapp/mine/db.py
:
class query_00:
def __init__(self, db_con, db_sql, db_stmt = []):
self.db_con = db_con
self.db_sql = db_sql
self.fields = []
with db_con.cursor() as self.query:
self.query.execute(db_sql, db_stmt)
self.fields = [f.name for f in self.query.description]
# for entry in self.query:
# yield dict(zip(self.fields, entry))
# self.query = db_con.cursor()
# must return self, because
# AttributeError: 'NoneType' object has no attribute 'result'
def __enter__(self):
return self
# self.query.execute(self.db_sql, self.db_stmt)
# self.fields = [f.name for f in self.query.description]
# pass
def __exit__(self, exc_type, exc_value, traceback):
# is this necessary?
# self.db_con.close()
pass
def result(self):
for entry in self.query.fetchall():
yield dict(zip(self.fields, entry))
# not working
# for entry in self.query:
# yield dict(zip(self.fields, entry))
# not working
# yield dict(zip(self.fields, entry))
# pass
然后我在./manage.py shell
上输入
from django.db import (connection as con)
from mine.db import query_00
# expected usage, attempt 1
q = query_00(con, 'SELECT * FROM master.years a where a.year = %s', [str(2019),])
for b in q.result():
print(b)
# expected usage, attempt 2
with query_00(con, 'SELECT * FROM master.years a where a.year = %s', [str(2019),]) as q:
for b in q.result():
print(b)
python-3,django-2,postgresql-9
(对不起我的英文)
所以,在阅读文档后,我意识到连接在我的 init 方法中关闭了。
class query_00:
def __init__(self, db_con, db_sql, db_stmt = []):
self.db_con = db_con
self.db_sql = db_sql
self.fields = []
with db_con.cursor() as self.query:
self.query.execute(db_sql, db_stmt)
self.fields = [f.name for f in self.query.description]
# the connection only happend inside "with:" block
# the connection, was already closed here (after with:)
所以,我只需要将 cursor() 保持在一个变量上
class query_01:
def __init__(self, db_sql, db_stmt):
self.db_sql = db_sql
self.db_stmt = db_stmt
self.query = connection.cursor()
...
将query.execute()
放在另一个方法上
...
def execute(self):
self.query.execute(self.db_sql, self.db_stmt)
self.fields = [f.name for f in self.query.description]
...
结果()
...
def result(self):
self.execute()
for entry in self.query:
yield self.keyvalue(entry)
...
那么我的 class 正在工作
with query_00('SELECT * FROM master.years a where a.year = %s', [str(2019),]) as q:
for b in q.result():
print(b)