Skip to content

Commit 933838d

Browse files
committed
Add support for handling postgres meta commands via pgspecial.
1 parent 82240bb commit 933838d

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
'sqlalchemy>=0.6.7',
1515
'sqlparse',
1616
'six',
17+
'pgspecial',
1718
'ipython-genutils>=0.1.0',
1819
]
1920

src/sql/run.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import sqlalchemy
1010
import sqlparse
1111
import prettytable
12+
from pgspecial.main import PGSpecial
1213
from .column_guesser import ColumnGuesserMixin
1314

1415

@@ -141,7 +142,7 @@ def __getitem__(self, key):
141142
return result[0]
142143
def dict(self):
143144
"""Returns a single dict built from the result set
144-
145+
145146
Keys are column names; values are a tuple"""
146147
return dict(zip(self.keys, zip(*self)))
147148

@@ -274,19 +275,38 @@ def interpret_rowcount(rowcount):
274275
result = '%d rows affected.' % rowcount
275276
return result
276277

278+
class FakeResultProxy(object):
279+
"""A fake class that pretends to behave like the ResultProxy from
280+
SqlAlchemy.
281+
"""
282+
def __init__(self, cursor, headers):
283+
self.fetchall = cursor.fetchall
284+
self.fetchmany = cursor.fetchmany
285+
self.rowcount = cursor.rowcount
286+
self.keys = lambda: headers
287+
self.returns_rows = True
288+
277289

278290
def run(conn, sql, config, user_namespace):
279291
if sql.strip():
280292
for statement in sqlparse.split(sql):
281-
if sql.strip().split()[0].lower() == 'begin':
293+
first_word = sql.strip().split()[0].lower()
294+
if first_word == 'begin':
282295
raise Exception("ipython_sql does not support transactions")
283-
txt = sqlalchemy.sql.text(statement)
284-
result = conn.session.execute(txt, user_namespace)
296+
if first_word.startswith('\\') and 'postgres' in str(conn.dialect):
297+
pgspecial = PGSpecial()
298+
_, cur, headers, _ = pgspecial.execute(
299+
conn.session.connection.cursor(),
300+
statement)[0]
301+
result = FakeResultProxy(cur, headers)
302+
else:
303+
txt = sqlalchemy.sql.text(statement)
304+
result = conn.session.execute(txt, user_namespace)
285305
try:
286306
# mssql has autocommit
287307
if 'mssql' not in str(conn.dialect):
288308
conn.session.execute('commit')
289-
except sqlalchemy.exc.OperationalError:
309+
except sqlalchemy.exc.OperationalError:
290310
pass # not all engines can commit
291311
if result and config.feedback:
292312
print(interpret_rowcount(result.rowcount))

0 commit comments

Comments
 (0)