Skip to content

Conversation

@meeuw
Copy link
Contributor

@meeuw meeuw commented Jun 9, 2017

Description

output via generator to prevent:

  • buffering of the complete output
  • joining and splitting the output

Checklist

  • I've added this contribution to the changelog.md.

@meeuw meeuw force-pushed the feature/output_via_generator branch from 7c9066a to 6d0e7fb Compare June 9, 2017 13:00
mycli/main.py Outdated
rows, headers, format_name='vertical')

output.append(formatted)
if isinstance(formatted, str) or isinstance(formatted, unicode):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to try adding from mycli.encodingutils import text_type to main.py so you can use that here.

mycli/main.py Outdated
from .lexer import MyCliLexer
from .__init__ import __version__

from mycli.encodingutils import text_type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I told you wrong - you can add this to line 39 where we are already importing from encodingutils ;) Sorry about that!

mycli/main.py Outdated

output.append(formatted)
if isinstance(formatted, text_type):
formatted = formatted.splitlines()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is formatted not a text_type? I think CLI Helpers always returns a text_type.

@tsroten
Copy link
Member

tsroten commented Jun 12, 2017

@meeuw Thanks for looking for more ways to improve mycli 😄

So, I'm wondering, what's the advantage of operating on the line level? I'm having trouble understanding what that gets us versus what we have now.

Tabulate and Terminaltables don't return lists or iterables, so it's not like we can process the lines separately. This seems like it calls quite a bit of code for every line.

@meeuw
Copy link
Contributor Author

meeuw commented Jun 12, 2017

Terminaltables is capable of returning an iterable, I'm working on a fix for cli_helpers. Terminaltables still needs to process the complete result set before outputting (to calculate the column width). But for csv/json/xml/tsv/wide output it's possible to iterate the database cursor and format/output the data without buffering the complete result set in memory.

@tsroten
Copy link
Member

tsroten commented Jun 12, 2017

@meeuw Cool, sounds good to me 😄. Should I review this pull request? Or, wait until the CLI Helpers pull request?

@meeuw meeuw force-pushed the feature/output_via_generator branch 2 times, most recently from 1e49d7f to 2ad542a Compare June 18, 2017 09:28
@codecov-io
Copy link

codecov-io commented Jun 18, 2017

Codecov Report

Merging #461 into master will increase coverage by 0.78%.
The diff coverage is 97.36%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #461      +/-   ##
==========================================
+ Coverage   77.83%   78.61%   +0.78%     
==========================================
  Files          22       22              
  Lines        2012     2034      +22     
==========================================
+ Hits         1566     1599      +33     
+ Misses        446      435      -11
Impacted Files Coverage Δ
mycli/main.py 79.76% <97.36%> (+2.39%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2934073...e9b3949. Read the comment docs.

@meeuw
Copy link
Contributor Author

meeuw commented Jun 18, 2017

Related to dbcli/cli_helpers#13

mycli/main.py Outdated
click.secho(output)
size = self.cli.output.get_size()

margin = self.get_reserved_space() + self.get_prompt(self.prompt_format).count('\n') + 1
Copy link
Member

@tsroten tsroten Jun 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get why you're not calling output_fits_on_screen any longer (it compares the entire output), but let's rework that function so we can call it to get the margin so the margin code isn't directly in the output() function.

Since output_fits_on_screen is not used elsewhere, we can rename it and tweak it.

E.g. get_output_margin or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I accidentally removed output_fits_on_screen when I was resolving the merge conflicts, thanks for noticing, I'll try to fix it as soon as possible 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm that's a good idea, fixed this.

mycli/main.py Outdated

output.append(formatted)
if not isinstance(formatted, types.GeneratorType):
formatted = formatted.splitlines()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@meeuw, so if I understand this correctly, this line won't be needed once the CLI helpers changes are made, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exactly

@tsroten
Copy link
Member

tsroten commented Jun 24, 2017

@meeuw I'd like to get this in for our next mycli release (so mycli will be ready whenever the next CLI Helpers is released with the generator change).

I'll test it out this weekend. Other than that, the only change I think would be good is this one.

@meeuw meeuw force-pushed the feature/output_via_generator branch 4 times, most recently from 5d60435 to 162e824 Compare June 24, 2017 19:30
@tsroten
Copy link
Member

tsroten commented Jun 24, 2017

So, one thing that's come up in my testing is that the output is always outputted to the pager, even if it fits on the screen. That's how mycli used to output results, but we recently changed it to only output via the pager if it doesn't fit (or there is the explicit pager).

@meeuw meeuw force-pushed the feature/output_via_generator branch from 162e824 to 107be90 Compare June 25, 2017 11:44
@meeuw
Copy link
Contributor Author

meeuw commented Jun 25, 2017

Ah you're right. I think I fixed it but I'd like to add additional tests.

@meeuw meeuw force-pushed the feature/output_via_generator branch 2 times, most recently from aecef31 to 0614e08 Compare June 29, 2017 08:32
@meeuw
Copy link
Contributor Author

meeuw commented Jun 29, 2017

@tsroten I've added the additional tests but I think they could be a little bit more Pythonic and/or use more pytest features.

@meeuw meeuw force-pushed the feature/output_via_generator branch from 0614e08 to 80185c8 Compare July 2, 2017 06:27
@meeuw meeuw force-pushed the feature/output_via_generator branch from 80185c8 to 9e96d36 Compare July 2, 2017 06:52
@meeuw
Copy link
Contributor Author

meeuw commented Jul 2, 2017

I'm thinking of using this to check if a generator returned from cli_helpers, but I don't like to add six as a dependency.

@meeuw
Copy link
Contributor Author

meeuw commented Jul 5, 2017

I've created a PR: pallets/click#815 to allow outputting to the pager using a generator

@meeuw
Copy link
Contributor Author

meeuw commented Jul 9, 2017

@tsroten thanks, could you please update the tests or tell me how, "if the output doesn't fit and it's not going to be output via a pager, then we lose all the rows after fits is set to False?"

@tsroten
Copy link
Member

tsroten commented Jul 9, 2017

@meeuw Ok, I added a test that is failing. You can replicate it by:

  1. opening mycli
  2. turn off the pager by running nopager.
  3. run a query that will give you results longer or wider than the console.

You should see the results cut off because the output stops appending to buf.

@meeuw
Copy link
Contributor Author

meeuw commented Jul 10, 2017

You're the best 😄 thanks a lot! Fixed.

mycli/main.py Outdated
for i, line in enumerate(output, 1):
self.log_output(line)
# line needs to be casted to unicode for click with Python 2.7
special.write_tee(text_type(line))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to fix whatever is not returning unicode. Do you know what it is? I know the CSV part of CLI Helpers wasn't at one point, but that should be fixed in the version that mycli requires.

If we can't fix it, then, we'll need to convert to unicode for the call to write_once() as well (line 715).

mycli/main.py Outdated
**output_kwargs)
first_line = formatted[:formatted.find('\n')]

if isinstance(formatted, (str, text_type)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can drop str now that the unicode problems in CLI Helpers were fixed.

mycli/main.py Outdated
len(first_line) > max_width):
formatted = self.formatter.format_output(
cur, headers, format_name='vertical', column_types=column_types, **output_kwargs)
if isinstance(formatted, (str, text_type)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here ^^

@meeuw
Copy link
Contributor Author

meeuw commented Aug 7, 2017

👍 thanks, the cast isn't required anymore.

@tsroten
Copy link
Member

tsroten commented Aug 7, 2017

@meeuw Good work! I think this is ready to merge. If you could just move the changelog line up to the pending release, we'll be all set.

I wonder if there is a way to word this change so that the end-user understands it.

@meeuw
Copy link
Contributor Author

meeuw commented Aug 7, 2017

I've rephrased the changelog, English isn't my first language, could you please review? Feel free to change the text.

@tsroten
Copy link
Member

tsroten commented Aug 8, 2017

@meeuw Ok, I reworded the changelog to be a bit shorter. It indicates that this is preliminary work to use less memory (preliminary, since CLI Helpers is still returning a string and not a generator).

If you agree with the change, then go ahead and merge this in! It'll be good to get this one in finally. Sorry it took so long!

👍 🚀

@meeuw meeuw merged commit e05cdcf into master Aug 8, 2017
@meeuw meeuw deleted the feature/output_via_generator branch August 8, 2017 17:07
@meeuw
Copy link
Contributor Author

meeuw commented Aug 8, 2017

I'm not in a hurry, thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants