diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-04-02 22:33:50 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-04-02 22:33:50 +0000 |
commit | bf77ddaabb8a39f292a649e51f84e8a9af397de7 (patch) | |
tree | fa15dc086012f8bf3bc3f7510d70b989683f1a3c /lib/sqlalchemy/databases/postgres.py | |
parent | 0359a6a13dbe02b680e14cd830206544206153b8 (diff) | |
download | sqlalchemy-bf77ddaabb8a39f292a649e51f84e8a9af397de7.tar.gz |
- Got PG server side cursors back into shape, added fixed
unit tests as part of the default test suite. Added
better uniqueness to the cursor ID [ticket:1001]
- update().values() and insert().values() take keyword
arguments.
Diffstat (limited to 'lib/sqlalchemy/databases/postgres.py')
-rw-r--r-- | lib/sqlalchemy/databases/postgres.py | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/lib/sqlalchemy/databases/postgres.py b/lib/sqlalchemy/databases/postgres.py index 94ad7d2e4..326dd6b7d 100644 --- a/lib/sqlalchemy/databases/postgres.py +++ b/lib/sqlalchemy/databases/postgres.py @@ -224,6 +224,10 @@ def descriptor(): ('host',"Hostname", None), ]} +SERVER_SIDE_CURSOR_RE = re.compile( + r'\s*SELECT', + re.I | re.UNICODE) + SELECT_RE = re.compile( r'\s*(?:SELECT|FETCH|(UPDATE|INSERT))', re.I | re.UNICODE) @@ -252,7 +256,6 @@ RETURNING_QUOTED_RE = re.compile( \sRETURNING\s""", re.I | re.UNICODE | re.VERBOSE) class PGExecutionContext(default.DefaultExecutionContext): - def returns_rows_text(self, statement): m = SELECT_RE.match(statement) return m and (not m.group(1) or (RETURNING_RE.search(statement) @@ -265,23 +268,20 @@ class PGExecutionContext(default.DefaultExecutionContext): ) def create_cursor(self): - # executing a default or Sequence standalone creates an execution context without a statement. - # so slightly hacky "if no statement assume we're server side" logic - # TODO: dont use regexp if Compiled is used ? self.__is_server_side = \ self.dialect.server_side_cursors and \ - (self.statement is None or \ - (SELECT_RE.match(self.statement) and not re.search(r'FOR UPDATE(?: NOWAIT)?\s*$', self.statement, re.I)) - ) + ((self.compiled and isinstance(self.compiled.statement, expression.Selectable)) \ + or \ + (not self.compiled and self.statement and SERVER_SIDE_CURSOR_RE.match(self.statement))) if self.__is_server_side: # use server-side cursors: # http://lists.initd.org/pipermail/psycopg/2007-January/005251.html - ident = "c" + hex(random.randint(0, 65535))[2:] + ident = "c_%s_%s" % (hex(id(self))[2:], hex(random.randint(0, 65535))[2:]) return self._connection.connection.cursor(ident) else: return self._connection.connection.cursor() - + def get_result_proxy(self): if self.__is_server_side: return base.BufferedRowResultProxy(self) @@ -763,6 +763,11 @@ class PGSchemaDropper(compiler.SchemaDropper): self.execute() class PGDefaultRunner(base.DefaultRunner): + def __init__(self, context): + base.DefaultRunner.__init__(self, context) + # craete cursor which won't conflict with a server-side cursor + self.cursor = context._connection.connection.cursor() + def get_column_default(self, column, isinsert=True): if column.primary_key: # pre-execute passive defaults on primary keys |