summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/databases/postgres.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-04-02 22:33:50 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-04-02 22:33:50 +0000
commitbf77ddaabb8a39f292a649e51f84e8a9af397de7 (patch)
treefa15dc086012f8bf3bc3f7510d70b989683f1a3c /lib/sqlalchemy/databases/postgres.py
parent0359a6a13dbe02b680e14cd830206544206153b8 (diff)
downloadsqlalchemy-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.py23
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