3
3
import psycopg
4
4
import psycopg_pool
5
5
from psycopg .rows import namedtuple_row
6
- from sqlalchemy .engine .interfaces import Dialect
7
6
from sqlalchemy .dialects .postgresql .psycopg import PGDialect_psycopg
7
+ from sqlalchemy .engine .interfaces import Dialect
8
8
from sqlalchemy .sql import ClauseElement
9
+ from sqlalchemy .sql .schema import Column
9
10
10
11
from databases .backends .common .records import Record , create_column_maps
11
12
from databases .core import DatabaseURL
@@ -31,6 +32,7 @@ def __init__(
31
32
self ._database_url = DatabaseURL (database_url )
32
33
self ._options = options
33
34
self ._dialect = PGDialect_psycopg ()
35
+ self ._dialect .implicit_returning = True
34
36
self ._pool = None
35
37
36
38
async def connect (self ) -> None :
@@ -94,7 +96,7 @@ async def fetch_all(self, query: ClauseElement) -> typing.List[RecordInterface]:
94
96
rows = await cursor .fetchall ()
95
97
96
98
column_maps = create_column_maps (result_columns )
97
- return [Record (row , result_columns , self ._dialect , column_maps ) for row in rows ]
99
+ return [PsycopgRecord (row , result_columns , self ._dialect , column_maps ) for row in rows ]
98
100
99
101
async def fetch_one (self , query : ClauseElement ) -> typing .Optional [RecordInterface ]:
100
102
if self ._connection is None :
@@ -109,7 +111,7 @@ async def fetch_one(self, query: ClauseElement) -> typing.Optional[RecordInterfa
109
111
if row is None :
110
112
return None
111
113
112
- return Record (
114
+ return PsycopgRecord (
113
115
row ,
114
116
result_columns ,
115
117
self ._dialect ,
@@ -154,7 +156,7 @@ async def iterate(
154
156
if row is None :
155
157
break
156
158
157
- yield Record (row , result_columns , self ._dialect , column_maps )
159
+ yield PsycopgRecord (row , result_columns , self ._dialect , column_maps )
158
160
159
161
def transaction (self ) -> "TransactionBackend" :
160
162
return PsycopgTransaction (connection = self )
@@ -214,3 +216,21 @@ async def rollback(self) -> None:
214
216
215
217
async with self ._transaction ._conn .lock :
216
218
await self ._transaction ._conn .wait (self ._transaction ._rollback_gen (None ))
219
+
220
+
221
+ class PsycopgRecord (Record ):
222
+ @property
223
+ def _mapping (self ) -> typing .Mapping :
224
+ return self ._row ._asdict ()
225
+
226
+ def __getitem__ (self , key : typing .Any ) -> typing .Any :
227
+ if len (self ._column_map ) == 0 :
228
+ return self ._mapping [key ]
229
+ elif isinstance (key , Column ):
230
+ idx , datatype = self ._column_map_full [str (key )]
231
+ elif isinstance (key , int ):
232
+ idx , datatype = self ._column_map_int [key ]
233
+ else :
234
+ idx , datatype = self ._column_map [key ]
235
+
236
+ return self ._row [idx ]
0 commit comments