102 self.keep_alive = keep_alive |
102 self.keep_alive = keep_alive |
103 self.init_statement = init_statement |
103 self.init_statement = init_statement |
104 self.pool_size = pool_size |
104 self.pool_size = pool_size |
105 |
105 |
106 |
106 |
107 class RowDict: |
107 class RowDict(OrderedDict): |
108 """Special read-only dictionary used for rows returned from queries. |
108 """Special dictionary used for rows returned from queries. |
109 |
|
110 Initialization is same as for dict: |
|
111 row = RowDict([('id', 123), ('name', 'hello')]) |
|
112 |
|
113 Allows key and attribute access to contained items: |
|
114 row['id'] |
|
115 row.id |
|
116 |
109 |
117 Items keep order in which columns where returned from database. |
110 Items keep order in which columns where returned from database. |
118 |
111 |
119 Tuple style access is also supported: |
112 It supports three styles of access: |
120 row[0] |
113 |
121 id, name = row |
114 Dict style: |
|
115 row['id'] |
|
116 for key in row: |
|
117 ... |
|
118 |
|
119 Object style (only works if column name does not collide with any method name): |
|
120 row.id |
|
121 |
|
122 Tuple style: |
|
123 row[0] |
|
124 id, name = row.values() |
122 |
125 |
123 """ |
126 """ |
124 |
|
125 def __init__(self, data): |
|
126 self._dict = OrderedDict(data) |
|
127 |
127 |
128 def __getitem__(self, key): |
128 def __getitem__(self, key): |
129 if isinstance(key, int): |
129 if isinstance(key, int): |
130 return tuple(self._dict.values())[key] |
130 return tuple(self.values())[key] |
131 return self._dict[key] |
131 else: |
|
132 return OrderedDict.__getitem__(self, key) |
132 |
133 |
133 def __getattr__(self, key): |
134 def __getattr__(self, key): |
134 try: |
135 try: |
135 return self._dict[key] |
136 return self[key] |
136 except KeyError: |
137 except KeyError: |
137 raise AttributeError(key) |
138 raise AttributeError(key) |
138 |
|
139 def __contains__(self, key): |
|
140 return key in self._dict |
|
141 |
|
142 def keys(self): |
|
143 return self._dict.keys() |
|
144 |
|
145 def values(self): |
|
146 return self._dict.values() |
|
147 |
|
148 def items(self): |
|
149 return self._dict.items() |
|
150 |
|
151 def __repr__(self): |
|
152 return 'RowDict(%s)' % str(self._dict.items()) |
|
153 |
139 |
154 |
140 |
155 class Cursor(psycopg2.extensions.cursor): |
141 class Cursor(psycopg2.extensions.cursor): |
156 |
142 |
157 def execute(self, query, args=None): |
143 def execute(self, query, args=None): |
489 return psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT |
475 return psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT |
490 if level.lower() == 'read_committed': |
476 if level.lower() == 'read_committed': |
491 return psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED |
477 return psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED |
492 if level.lower() == 'serializable': |
478 if level.lower() == 'serializable': |
493 return psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE |
479 return psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE |
494 raise PgManagerError('Unknown isolation level name: "%s"', level) |
480 raise PgManagerError('Unknown isolation level name: "%s"' % level) |
495 return level |
481 return level |
496 |
482 |
497 def _check_fork(self): |
483 def _check_fork(self): |
498 '''Check if process was forked (PID has changed). |
484 '''Check if process was forked (PID has changed). |
499 |
485 |