74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
import re
|
|
from collections import namedtuple
|
|
from functools import lru_cache
|
|
|
|
from .cursor import Cursor
|
|
|
|
|
|
class DictCursor(Cursor):
|
|
"""
|
|
A cursor that generates results as :class:`dict`.
|
|
|
|
``fetch*()`` methods will return dicts instead of tuples.
|
|
"""
|
|
|
|
def fetchone(self):
|
|
rv = super(DictCursor, self).fetchone()
|
|
if rv is not None:
|
|
rv = dict(zip(self._columns, rv))
|
|
return rv
|
|
|
|
def fetchmany(self, size=None):
|
|
rv = super(DictCursor, self).fetchmany(size=size)
|
|
return [dict(zip(self._columns, x)) for x in rv]
|
|
|
|
def fetchall(self):
|
|
rv = super(DictCursor, self).fetchall()
|
|
return [dict(zip(self._columns, x)) for x in rv]
|
|
|
|
|
|
class NamedTupleCursor(Cursor):
|
|
"""
|
|
A cursor that generates results as named tuples created by
|
|
:func:`~collections.namedtuple`.
|
|
|
|
``fetch*()`` methods will return named tuples instead of regular tuples, so
|
|
their elements can be accessed both as regular numeric items as well as
|
|
attributes.
|
|
"""
|
|
|
|
# ascii except alnum and underscore
|
|
_re_clean = re.compile(
|
|
'[' + re.escape(' !"#$%&\'()*+,-./:;<=>?@[\\]^`{|}~') + ']')
|
|
|
|
@classmethod
|
|
@lru_cache(512)
|
|
def _make_nt(self, key):
|
|
fields = []
|
|
for s in key:
|
|
s = self._re_clean.sub('_', s)
|
|
# Python identifier cannot start with numbers, namedtuple fields
|
|
# cannot start with underscore.
|
|
if s[0] == '_' or '0' <= s[0] <= '9':
|
|
s = 'f' + s
|
|
fields.append(s)
|
|
|
|
return namedtuple('Record', fields)
|
|
|
|
def fetchone(self):
|
|
rv = super(NamedTupleCursor, self).fetchone()
|
|
if rv is not None:
|
|
nt = self._make_nt(self._columns)
|
|
rv = nt(*rv)
|
|
return rv
|
|
|
|
def fetchmany(self, size=None):
|
|
rv = super(NamedTupleCursor, self).fetchmany(size=size)
|
|
nt = self._make_nt(self._columns)
|
|
return [nt(*x) for x in rv]
|
|
|
|
def fetchall(self):
|
|
rv = super(NamedTupleCursor, self).fetchall()
|
|
nt = self._make_nt(self._columns)
|
|
return [nt(*x) for x in rv]
|