Skip to content

Commit 1c58773

Browse files
Adjust displaylimit even of result sets already fetched
1 parent da6e51a commit 1c58773

File tree

4 files changed

+52
-21
lines changed

4 files changed

+52
-21
lines changed

HACKING.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
Development setup
22
=================
33

4-
Running nose tests with IPython is tricky, so there's a
4+
Running nose tests with IPython is tricky, so there's a
55
run_tests.sh script for it.
66

7+
To temporarily insert breakpoints for debugging: `from nose.tools import set_trace; set_trace()`
8+
9+
Tests have requirements not installed by setup.py:
10+
11+
- nose
12+
- pandas
13+
714
Release HOWTO
815
=============
916

10-
To make a release,
17+
To make a release,
1118

1219
1) Update release date/version in NEWS.txt and setup.py
1320
2) Run 'python setup.py sdist'
1421
3) Test the generated source distribution in dist/
1522
4) Upload to PyPI: 'python setup.py sdist register upload'
1623
5) Increase version in setup.py (for next release)
17-

src/sql/magic.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ class SqlMagic(Magics, Configurable):
2626
2727
Provides the %%sql magic."""
2828

29-
autolimit = Int(0, config=True, help="Automatically limit the size of the returned result sets")
29+
autolimit = Int(0, config=True, allow_none=True, help="Automatically limit the size of the returned result sets")
3030
style = Unicode('DEFAULT', config=True, help="Set the table printing style to any of prettytable's defined styles (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM)")
3131
short_errors = Bool(True, config=True, help="Don't display the full traceback on SQL Programming Error")
32-
displaylimit = Int(0, config=True, help="Automatically limit the number of rows displayed (full result set is still stored)")
32+
displaylimit = Int(None, config=True, allow_none=True, help="Automatically limit the number of rows displayed (full result set is still stored)")
3333
autopandas = Bool(False, config=True, help="Return Pandas DataFrames instead of regular result sets")
3434
column_local_vars = Bool(False, config=True, help="Return data into local variables from column names")
3535
feedback = Bool(True, config=True, help="Print number of rows affected by DML")
@@ -157,7 +157,7 @@ def load_ipython_extension(ip):
157157

158158
# this fails in both Firefox and Chrome for OS X.
159159
# I get the error: TypeError: IPython.CodeCell.config_defaults is undefined
160-
160+
161161
# js = "IPython.CodeCell.config_defaults.highlight_modes['magic_sql'] = {'reg':[/^%%sql/]};"
162162
# display_javascript(js, raw=True)
163163
ip.register_magics(SqlMagic)

src/sql/run.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,16 @@ def __init__(self, sqlaproxy, sql, config):
103103
else:
104104
list.__init__(self, sqlaproxy.fetchall())
105105
self.field_names = unduplicate_field_names(self.keys)
106-
self.pretty = prettytable.PrettyTable(self.field_names)
107-
if not config.autopandas:
108-
for row in self[:config.displaylimit or None]:
109-
self.pretty.add_row(row)
110-
self.pretty.set_style(self.style)
106+
self.pretty = PrettyTable(self.field_names, style=self.style)
107+
# self.pretty.set_style(self.style)
111108
else:
112109
list.__init__(self, [])
113110
self.pretty = None
111+
114112
def _repr_html_(self):
115113
_cell_with_spaces_pattern = re.compile(r'(<td>)( {2,})')
116114
if self.pretty:
115+
self.pretty.add_rows(self)
117116
result = self.pretty.get_html_string()
118117
result = _cell_with_spaces_pattern.sub(_nonbreaking_spaces, result)
119118
if self.config.displaylimit and len(self) > self.config.displaylimit:
@@ -122,8 +121,11 @@ def _repr_html_(self):
122121
return result
123122
else:
124123
return None
124+
125125
def __str__(self, *arg, **kwarg):
126+
self.pretty.add_rows(self)
126127
return str(self.pretty or '')
128+
127129
def __getitem__(self, key):
128130
"""
129131
Access by integer (row position within result set)
@@ -247,6 +249,7 @@ def csv(self, filename=None, **format_params):
247249
Any other parameters will be passed on to csv.writer."""
248250
if not self.pretty:
249251
return None # no results
252+
self.pretty.add_rows(self)
250253
if filename:
251254
encoding = format_params.get('encoding', 'utf-8')
252255
if six.PY2:
@@ -316,3 +319,25 @@ def run(conn, sql, config, user_namespace):
316319
#returning only last result, intentionally
317320
else:
318321
return 'Connected: %s' % conn.name
322+
323+
324+
class PrettyTable(prettytable.PrettyTable):
325+
326+
def __init__(self, *args, **kwargs):
327+
self.row_count = 0
328+
self.displaylimit = None
329+
return super(PrettyTable, self).__init__(*args, **kwargs)
330+
331+
def add_rows(self, data):
332+
if self.row_count and (data.config.displaylimit == self.displaylimit):
333+
return # correct number of rows already present
334+
self.clear_rows()
335+
self.displaylimit = data.config.displaylimit
336+
if self.displaylimit == 0:
337+
self.displaylimit = None # TODO: remove this to make 0 really 0
338+
if self.displaylimit in (None, 0):
339+
self.row_count = len(data)
340+
else:
341+
self.row_count = min(len(data), self.displaylimit)
342+
for row in data[:self.displaylimit]:
343+
self.add_row(row)

src/tests/test_magic.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_print():
3939
def test_plain_style():
4040
ip.run_line_magic('config', "SqlMagic.style = 'PLAIN_COLUMNS'")
4141
result = ip.run_line_magic('sql', "sqlite:// SELECT * FROM test;")
42-
assert re.search(r'1\s+foo', str(result))
42+
assert re.search(r'1\s+\|\s+foo', str(result))
4343

4444

4545
def _setup_writer():
@@ -120,23 +120,24 @@ def test_persist_frame_at_its_creation():
120120
persisted = ip.run_line_magic('sql', 'SELECT * FROM results')
121121
assert 'Shakespeare' in str(persisted)
122122

123-
# TODO: support
123+
# TODO: support
124124
# @with_setup(_setup_writer, _teardown_writer)
125125
# def test_persist_with_connection_info():
126126
# ip.run_cell("results = %sql SELECT * FROM writer;")
127127
# ip.run_line_magic('sql', 'sqlite:// PERSIST results.DataFrame()')
128128
# persisted = ip.run_line_magic('sql', 'SELECT * FROM results')
129129
# assert 'Shakespeare' in str(persisted)
130130

131-
@with_setup(_setup_writer, _teardown_writer)
132131
def test_displaylimit():
133-
ip.run_line_magic('config', "SqlMagic.autolimit = 0")
134-
ip.run_line_magic('config', "SqlMagic.displaylimit = 0")
135-
result = ip.run_line_magic('sql', "sqlite:// SELECT * FROM writer;")
136-
assert result._repr_html_().count("<tr>") == 3
132+
ip.run_line_magic('config', "SqlMagic.autolimit = None")
133+
ip.run_line_magic('config', "SqlMagic.displaylimit = None")
134+
result = ip.run_line_magic('sql', "sqlite:// SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) AS Result ORDER BY 1;")
135+
assert 'apple' in result._repr_html_()
136+
assert 'banana' in result._repr_html_()
137+
assert 'cherry' in result._repr_html_()
137138
ip.run_line_magic('config', "SqlMagic.displaylimit = 1")
138-
result = ip.run_line_magic('sql', "sqlite:// SELECT * FROM writer;")
139-
assert result._repr_html_().count("<tr>") == 2
139+
assert 'apple' in result._repr_html_()
140+
assert 'cherry' not in result._repr_html_()
140141

141142
@with_setup(_setup_writer, _teardown_writer)
142143
def test_column_local_vars():
@@ -210,4 +211,3 @@ def test_dicts():
210211
assert 'first_name' in row
211212
assert 'last_name' in row
212213
assert 'year_of_death' in row
213-

0 commit comments

Comments
 (0)