33import psycopg
44import psycopg_pool
55from psycopg .rows import namedtuple_row
6- from sqlalchemy .engine .interfaces import Dialect
76from sqlalchemy .dialects .postgresql .psycopg import PGDialect_psycopg
7+ from sqlalchemy .engine .interfaces import Dialect
88from sqlalchemy .sql import ClauseElement
9+ from sqlalchemy .sql .schema import Column
910
1011from databases .backends .common .records import Record , create_column_maps
1112from databases .core import DatabaseURL
@@ -31,6 +32,7 @@ def __init__(
3132 self ._database_url = DatabaseURL (database_url )
3233 self ._options = options
3334 self ._dialect = PGDialect_psycopg ()
35+ self ._dialect .implicit_returning = True
3436 self ._pool = None
3537
3638 async def connect (self ) -> None :
@@ -94,7 +96,7 @@ async def fetch_all(self, query: ClauseElement) -> typing.List[RecordInterface]:
9496 rows = await cursor .fetchall ()
9597
9698 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 ]
98100
99101 async def fetch_one (self , query : ClauseElement ) -> typing .Optional [RecordInterface ]:
100102 if self ._connection is None :
@@ -109,7 +111,7 @@ async def fetch_one(self, query: ClauseElement) -> typing.Optional[RecordInterfa
109111 if row is None :
110112 return None
111113
112- return Record (
114+ return PsycopgRecord (
113115 row ,
114116 result_columns ,
115117 self ._dialect ,
@@ -154,7 +156,7 @@ async def iterate(
154156 if row is None :
155157 break
156158
157- yield Record (row , result_columns , self ._dialect , column_maps )
159+ yield PsycopgRecord (row , result_columns , self ._dialect , column_maps )
158160
159161 def transaction (self ) -> "TransactionBackend" :
160162 return PsycopgTransaction (connection = self )
@@ -214,3 +216,21 @@ async def rollback(self) -> None:
214216
215217 async with self ._transaction ._conn .lock :
216218 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