Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lazy_query example #298

Closed
stepankuzmin opened this issue Oct 15, 2017 · 8 comments
Closed

lazy_query example #298

stepankuzmin opened this issue Oct 15, 2017 · 8 comments

Comments

@stepankuzmin
Copy link

Hi there! I want to stream a large set of rows from a database. I didn't find any examples of lazy_query and tried to do it like this:

let query = format!("select row_to_json({1}) from {0}.{1}", schema, table);

let trans = conn.transaction().unwrap();
let stmt = trans.prepare(&query).unwrap();
let result = stmt.lazy_query(&trans, &[], 2);

for rows in result {
    println!("row: {:?}", rows);
}

I'm getting LazyRows { name: "s0p0", row_limit: 2, remaining_rows: 2, more_rows: true } as result. So how can I get rows from LazyRows?

@sfackler
Copy link
Owner

You're missing an .unwrap() on the lazy_query call. Rather than iterating over the rows, you're iterating over the Ok value of the Result<LazyRows, Error>.

@stepankuzmin
Copy link
Author

stepankuzmin commented Oct 15, 2017

Thanks for reply, @sfackler! I've tried

let result = stmt.lazy_query(&trans, &[], 2).unwrap();

for row in result {
    println!("row: {:?}", row);
}

But the compiler says, that the trait Iterator is not implemented for LazyRows:

41 | /     for row in result {
42 | |         println!("row: {:?}", row);
43 | |     }
   | |_____^ `postgres::rows::LazyRows<'_, '_>` is not an iterator; maybe try calling `.iter()` or a similar method
   |
   = help: the trait `std::iter::Iterator` is not implemented for `postgres::rows::LazyRows<'_, '_>`
   = note: required by `std::iter::IntoIterator::into_iter`

P.S. I'm using

postgres = { version = "0.15.1", features = ["with-serde_json", "with-time", "with-uuid"] }

@sfackler
Copy link
Owner

Ah right - the other bit here is that LazyRows implements the FallibleIterator rather than the normal Iterator trait.

This should do what you want:

extern crate fallible_iterator;

use fallible_iterator::FallibleIterator;

let trans = conn.transaction().unwrap();
let stmt = trans.prepare(&query).unwrap();
let mut result = stmt.lazy_query(&trans, &[], 2).unwrap();

while let Some(row) = result.next().unwrap() {
    println!("row: {:?}", row);
}

@sfackler
Copy link
Owner

I've added an example to the documentation to make this less confusing: 89d39cc.

@stepankuzmin
Copy link
Author

stepankuzmin commented Oct 16, 2017

Great! Thanks!

@stepankuzmin
Copy link
Author

One more question: In the example above I'm querying 4k rows, but the body of while loop is only called once. It seems, that row_limit does not affect query.

@stepankuzmin stepankuzmin reopened this Oct 16, 2017
@sfackler
Copy link
Owner

The row limit doesn't affect the user-visible access to the rows, it just controls the batch size that those rows are loaded from the database. Loading rows in batches of 1 or batches of 4K will behave the same way when looping (other than 1 row per batch probably being a lost slower!).

@stepankuzmin
Copy link
Author

Wow, thanks! That's clear for me now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants