super(_PGArray, self).__init__(*arg, **kw) # Py2K # FIXME: this check won't work for setups that # have convert_unicode only on their create_engine(). if isinstance(self.item_type, sqltypes.String) and \ self.item_type.convert_unicode: self.item_type.convert_unicode = "force" # end Py2K # When we're handed literal SQL, ensure it's a SELECT-query. Since # 8.3, combining cursors and "FOR UPDATE" has been fine. SERVER_SIDE_CURSOR_RE = re.compile( r'\s*SELECT', re.I | re.UNICODE) _server_side_id = util.counter() class PGExecutionContext_psycopg2(PGExecutionContext): def create_cursor(self): # TODO: coverage for server side cursors + select.for_update() if self.dialect.server_side_cursors: is_server_side = \ self.execution_options.get('stream_results', True) and ( (self.compiled and isinstance(self.compiled.statement, expression.Selectable) \ or \ ( (not self.compiled or isinstance(self.compiled.statement, expression._TextClause)) and self.statement and SERVER_SIDE_CURSOR_RE.match(self.statement)) )
from sqlalchemy.dialects.mssql.base import MSDialect, MSSQLCompiler, MSIdentifierPreparer, MSExecutionContext from sqlalchemy import util from .connector import PyTDSConnector _server_side_id = util.counter() class SSCursor(object): def __init__(self, c): self._c = c self._name = None self._nrows = 0 self._row = 0 def execute(self, statement, parameters): _name = 'tc%08X' % _server_side_id() sql = 'DECLARE ' + _name + ' CURSOR GLOBAL SCROLL STATIC READ_ONLY FOR ' + statement #print(sql, parameters) self._c.execute(sql, parameters) self._name = _name sql = 'OPEN ' + _name self._c.execute(sql) self._c.execute('SELECT @@CURSOR_ROWS AS nrows') self._nrows = self._c.fetchone()[0] return self.fetchone() def close(self): sql = 'CLOSE '+self._name self._c.execute(sql) sql = 'DEALLOCATE '+self._name self._c.execute(sql) self._c.close() self._name = None