Merge lp:~stub/storm/bug-322206 into lp:storm

Proposed by Stuart Bishop
Status: Merged
Merged at revision: not available
Proposed branch: lp:~stub/storm/bug-322206
Merge into: lp:storm
Diff against target: 111 lines
To merge this branch: bzr merge lp:~stub/storm/bug-322206
Reviewer Review Type Date Requested Status
Thomas Herve (community) Approve
James Henstridge Approve
Review via email: mp+7926@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Stuart Bishop (stub) wrote :

Fix for Bug #322206 as discussed in the bug report.

This branch makes psycopg2 2.0.7 or higher required for Storm PostgreSQL support.

This branch removes the quoting workaround required for earlier versions of psycopg, where Storm inserted an 'E' before string representations to ensure strings are always validly quoted.

Revision history for this message
James Henstridge (jamesh) wrote :

Looks good to me. Only two points:

1. Is distutils.version part of the public API of distutils, or an implementation detail?

2. If we are going to require 2.0.7, we can also update PostgresTimeoutTracer to check for QueryCanceledError rather than checking the exception message. That doesn't need to happen in this branch though.

review: Approve
Revision history for this message
Stuart Bishop (stub) wrote :

On Mon, Jun 29, 2009 at 5:32 PM, James Henstridge<email address hidden> wrote:
> Review: Approve
> Looks good to me.  Only two points:
>
> 1. Is distutils.version part of the public API of distutils, or an implementation detail?

Its been around since at least Python 2.3, is not using private naming conventions and contains more documentation than code. Its not documented in the reference manual, but not that much of distutils is. I'd say it is public enough.

--
Stuart Bishop <email address hidden>
http://www.stuartbishop.net/

Revision history for this message
Thomas Herve (therve) wrote :

A nice cleanup. Two comments:

1) RawStrVariable import can now be removed.

2) The bug links to edge, it may be nicer to link to production lp.

+1!

review: Approve
Revision history for this message
Stuart Bishop (stub) wrote :

> A nice cleanup. Two comments:
>
> 1) RawStrVariable import can now be removed.
>
> 2) The bug links to edge, it may be nicer to link to production lp.

I've fixed both of these points. Thanks!

lp:~stub/storm/bug-322206 updated
310. By Stuart Bishop

Fix bug link and remove unnecessary import

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'storm/databases/postgres.py'
2--- storm/databases/postgres.py 2009-05-15 08:43:21 +0000
3+++ storm/databases/postgres.py 2009-07-06 13:20:11 +0000
4@@ -1,5 +1,5 @@
5 #
6-# Copyright (c) 2006, 2007 Canonical
7+# Copyright (c) 2006-2009 Canonical
8 #
9 # Written by Gustavo Niemeyer <gustavo@niemeyer.net>
10 #
11@@ -19,13 +19,23 @@
12 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 #
14 from datetime import datetime, date, time, timedelta
15+from distutils.version import LooseVersion
16
17 from storm.databases import dummy
18
19+# PostgreSQL support in Storm requires psycopg2 2.0.7 or greater.
20+# Earlier versions of psyocpg2 contain data loss bugs.
21+# See https://bugs.launchpad.net/storm/+bug/322206 for more details.
22+REQUIRED_PSYCOPG2_VERSION = LooseVersion('2.0.7')
23+PSYCOPG2_VERSION = None
24 try:
25 import psycopg2
26- import psycopg2.extensions
27-except:
28+ PSYCOPG2_VERSION = LooseVersion(psycopg2.__version__.split(' ')[0])
29+ if PSYCOPG2_VERSION < REQUIRED_PSYCOPG2_VERSION:
30+ psycopg2 = dummy
31+ else:
32+ import psycopg2.extensions
33+except ImportError:
34 psycopg2 = dummy
35
36 from storm.expr import (
37@@ -33,7 +43,7 @@
38 Sequence, Like, SQLToken, COLUMN, COLUMN_NAME, COLUMN_PREFIX, TABLE,
39 compile, compile_select, compile_insert, compile_set_expr, compile_like,
40 compile_sql_token)
41-from storm.variables import Variable, ListVariable, RawStrVariable
42+from storm.variables import Variable, ListVariable
43 from storm.database import Database, Connection, Result
44 from storm.exceptions import (
45 install_exceptions, DatabaseError, DatabaseModuleError, InterfaceError,
46@@ -193,24 +203,6 @@
47 return compile_sql_token(compile, expr, state)
48
49
50-def compile_str_variable_with_E(compile, variable, state):
51- """Include an E just before the placeholder of string variables.
52-
53- PostgreSQL 8.2 will issue a warning without it, and psycopg
54- will use the plain '' rather than E''. The problem is being
55- tracked at the following URL::
56-
57- http://www.initd.org/tracker/psycopg/ticket/202
58-
59- """
60- state.parameters.append(variable)
61- if type(variable.get(to_db=True)) is str:
62- return "E?"
63- return "?"
64-
65-psycopg_needs_E = None
66-
67-
68 class PostgresResult(Result):
69
70 def get_insert_identity(self, primary_key, primary_variables):
71@@ -314,7 +306,9 @@
72
73 def __init__(self, uri):
74 if psycopg2 is dummy:
75- raise DatabaseModuleError("'psycopg2' module not found")
76+ raise DatabaseModuleError(
77+ "'psycopg2' >= %s not found. Found %s."
78+ % (REQUIRED_PSYCOPG2_VERSION, PSYCOPG2_VERSION))
79 self._dsn = make_dsn(uri)
80 isolation = uri.options.get("isolation", "serializable")
81 isolation_mapping = {
82@@ -340,29 +334,8 @@
83 cursor.execute("SHOW server_version_num")
84 except psycopg2.ProgrammingError:
85 self._version = 0
86- raw_connection.rollback()
87 else:
88 self._version = int(cursor.fetchone()[0])
89-
90- # This will conditionally change the compilation of binary
91- # variables (RawStrVariable) to preceed the placeholder with an
92- # 'E', if psycopg isn't doing it by itself.
93- #
94- # The "failing" code path isn't unittested because that
95- # would depend on a working psycopg version, or in an older
96- # postgresql version. Both branches were manually tested
97- # for correctness at some point.
98- global psycopg_needs_E
99- try:
100- # If psycopg behaves correctly, this will break trying
101- # to run a query with EE''.
102- cursor.execute("SELECT E%s", (psycopg2.Binary(""),))
103- except psycopg2.ProgrammingError:
104- psycopg_needs_E = False
105- else:
106- psycopg_needs_E = True
107- compile.when(RawStrVariable)(compile_str_variable_with_E)
108-
109 raw_connection.rollback()
110
111 raw_connection.set_client_encoding("UTF8")

Subscribers

People subscribed via source and target branches

to status/vote changes: