Skip to content

Commit 2c01a9d

Browse files
Merge branch 'amjith-master'
2 parents 82240bb + ed1a0fd commit 2c01a9d

File tree

4 files changed

+51
-21
lines changed

4 files changed

+51
-21
lines changed

README.rst

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -234,19 +234,6 @@ If you have installed ``matplotlib``, you can use a result set's
234234
.. image:: https://raw.github.com/catherinedevlin/ipython-sql/master/examples/wordcount.png
235235
:alt: pie chart of word count of Shakespeare's comedies
236236

237-
238-
Installing
239-
----------
240-
241-
Install the lastest release with::
242-
243-
pip install ipython-sql
244-
245-
or download from https://github.com/catherinedevlin/ipython-sql and::
246-
247-
cd ipython-sql
248-
sudo python setup.py install
249-
250237
Dumping
251238
-------
252239

@@ -260,6 +247,28 @@ specified) or in a file of the given name.
260247
261248
In[9]: result.csv(filename='work.csv')
262249
250+
PostgreSQL features
251+
-------------------
252+
253+
``psql``-style "backslash" `meta-commands`_ commands (``\d``, ``\dt``, etc.)
254+
are provided by `PGSpecial`_.
255+
256+
.. _PGSpecial: https://pypi.python.org/pypi/pgspecial
257+
258+
.. _meta-commands: https://www.postgresql.org/docs/9.6/static/app-psql.html#APP-PSQL-META-COMMANDS
259+
260+
Installing
261+
----------
262+
263+
Install the lastest release with::
264+
265+
pip install ipython-sql
266+
267+
or download from https://github.com/catherinedevlin/ipython-sql and::
268+
269+
cd ipython-sql
270+
sudo python setup.py install
271+
263272
Development
264273
-----------
265274

@@ -280,6 +289,7 @@ Credits
280289
- Michael Erasmus for DataFrame truth bugfix
281290
- Noam Finkelstein for README clarification
282291
- Xiaochuan Yu for `<<` operator, syntax colorization
292+
- Amjith Ramanujam for PGSpecial and incorporating it here
283293

284294
.. _Distribute: http://pypi.python.org/pypi/distribute
285295
.. _Buildout: http://www.buildout.org/

run_tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
#!/bin/bash
12
ipython -c "import nose; nose.run()"
23
# Insert breakpoints with `from nose.tools import set_trace; set_trace()`

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from setuptools import setup, find_packages
2-
import sys, os
2+
import os
33

44
here = os.path.abspath(os.path.dirname(__file__))
55
README = open(os.path.join(here, 'README.rst')).read()
@@ -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 & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import functools
21
import operator
3-
import types
42
import csv
53
import six
64
import codecs
@@ -9,6 +7,7 @@
97
import sqlalchemy
108
import sqlparse
119
import prettytable
10+
from pgspecial.main import PGSpecial
1211
from .column_guesser import ColumnGuesserMixin
1312

1413

@@ -141,7 +140,7 @@ def __getitem__(self, key):
141140
return result[0]
142141
def dict(self):
143142
"""Returns a single dict built from the result set
144-
143+
145144
Keys are column names; values are a tuple"""
146145
return dict(zip(self.keys, zip(*self)))
147146

@@ -274,19 +273,38 @@ def interpret_rowcount(rowcount):
274273
result = '%d rows affected.' % rowcount
275274
return result
276275

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

278288
def run(conn, sql, config, user_namespace):
279289
if sql.strip():
280290
for statement in sqlparse.split(sql):
281-
if sql.strip().split()[0].lower() == 'begin':
291+
first_word = sql.strip().split()[0].lower()
292+
if first_word == 'begin':
282293
raise Exception("ipython_sql does not support transactions")
283-
txt = sqlalchemy.sql.text(statement)
284-
result = conn.session.execute(txt, user_namespace)
294+
if first_word.startswith('\\') and 'postgres' in str(conn.dialect):
295+
pgspecial = PGSpecial()
296+
_, cur, headers, _ = pgspecial.execute(
297+
conn.session.connection.cursor(),
298+
statement)[0]
299+
result = FakeResultProxy(cur, headers)
300+
else:
301+
txt = sqlalchemy.sql.text(statement)
302+
result = conn.session.execute(txt, user_namespace)
285303
try:
286304
# mssql has autocommit
287305
if 'mssql' not in str(conn.dialect):
288306
conn.session.execute('commit')
289-
except sqlalchemy.exc.OperationalError:
307+
except sqlalchemy.exc.OperationalError:
290308
pass # not all engines can commit
291309
if result and config.feedback:
292310
print(interpret_rowcount(result.rowcount))

0 commit comments

Comments
 (0)