Skip to content

Commit 2ece79c

Browse files
feat: Add get_cursor() method to database adapters
Add get_cursor() abstract method to DatabaseAdapter base class and implement it in MySQLAdapter and PostgreSQLAdapter. This method provides backend-specific cursor creation for both tuple and dictionary result sets. Changes: - DatabaseAdapter.get_cursor(connection, as_dict=False) abstract method - MySQLAdapter.get_cursor() returns pymysql.cursors.Cursor or DictCursor - PostgreSQLAdapter.get_cursor() returns psycopg2 cursor or RealDictCursor This is part of Phase 4: Integrating adapters into the Connection class. All mypy checks passing. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 1cec906 commit 2ece79c

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

src/datajoint/adapters/base.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,27 @@ def default_port(self) -> int:
114114
"""
115115
...
116116

117+
@abstractmethod
118+
def get_cursor(self, connection: Any, as_dict: bool = False) -> Any:
119+
"""
120+
Get a cursor from the database connection.
121+
122+
Parameters
123+
----------
124+
connection : Any
125+
Database connection object.
126+
as_dict : bool, optional
127+
If True, return cursor that yields rows as dictionaries.
128+
If False, return cursor that yields rows as tuples.
129+
Default False.
130+
131+
Returns
132+
-------
133+
Any
134+
Database cursor object (backend-specific).
135+
"""
136+
...
137+
117138
# =========================================================================
118139
# SQL Syntax
119140
# =========================================================================

src/datajoint/adapters/mysql.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,29 @@ def default_port(self) -> int:
137137
"""MySQL default port 3306."""
138138
return 3306
139139

140+
def get_cursor(self, connection: Any, as_dict: bool = False) -> Any:
141+
"""
142+
Get a cursor from MySQL connection.
143+
144+
Parameters
145+
----------
146+
connection : Any
147+
pymysql connection object.
148+
as_dict : bool, optional
149+
If True, return DictCursor that yields rows as dictionaries.
150+
If False, return standard Cursor that yields rows as tuples.
151+
Default False.
152+
153+
Returns
154+
-------
155+
Any
156+
pymysql cursor object.
157+
"""
158+
import pymysql
159+
160+
cursor_class = pymysql.cursors.DictCursor if as_dict else pymysql.cursors.Cursor
161+
return connection.cursor(cursor=cursor_class)
162+
140163
# =========================================================================
141164
# SQL Syntax
142165
# =========================================================================

src/datajoint/adapters/postgres.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,30 @@ def default_port(self) -> int:
150150
"""PostgreSQL default port 5432."""
151151
return 5432
152152

153+
def get_cursor(self, connection: Any, as_dict: bool = False) -> Any:
154+
"""
155+
Get a cursor from PostgreSQL connection.
156+
157+
Parameters
158+
----------
159+
connection : Any
160+
psycopg2 connection object.
161+
as_dict : bool, optional
162+
If True, return Real DictCursor that yields rows as dictionaries.
163+
If False, return standard cursor that yields rows as tuples.
164+
Default False.
165+
166+
Returns
167+
-------
168+
Any
169+
psycopg2 cursor object.
170+
"""
171+
import psycopg2.extras
172+
173+
if as_dict:
174+
return connection.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
175+
return connection.cursor()
176+
153177
# =========================================================================
154178
# SQL Syntax
155179
# =========================================================================

0 commit comments

Comments
 (0)