-
-
Notifications
You must be signed in to change notification settings - Fork 802
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
Make #stmt.each async, and use stream/pipe #686
Comments
.each will give you rows one-by-one. It loads each row as it calls each callback. Happy to accept a PR implementing a |
How about if when
would also work as an async function/fatarrow handler.
This assumes each returns a Promise, and handles waiting in each iterable. |
Fine with either as a PR, the difference between expressing as async, promises, and callbacks here seems slim. node-sqlite3 currently supports v0.10 (which doesn't support promises), but we're dropping compatibility at the end of the month. |
Is anyone working on a PR for this? otherwise I might have a go at it. It has not been mentioned here, so I just wanted to point out that you can create a wrapper using |
I couldn't stop myself and had a look through the sources yesterday, and it seems more complicated to implement than what I first anticipated. Here are my findings, please correct any mistakes I've made in my reasoning (I have not looked at libuv before either, but I do know my way around general threading issues): The However breaking the
will have problems to properly schedule all the So I don't know what your feelings are, but to remain backwards compatible I don't think modifying I created a new What are your thoughts on this idea? |
From my own testing, |
@paolo-tanium It depends on how fast your javascript handler is and the time allocation between the threads. So if you handler is fast enough (faster than loading rows from db) then you shouldn't see a memory spike. On the other hand if the handler is slow then the rows will wait in memory until the handler can process them (and we see a memory spike). At least in theory, in practice the OS might decide to give lots of time to the loader thread before the handler is invoked and then everything will be loaded into memory even with a fast handler. So you are right that when you have a huge number of rows then you can't use |
@erikman was there any further progress on getMultiple? I'm experimenting with your fork which seems to work. |
@mhat I have not received any comments on it so I don't really know what to do with it. It works fine for me and I get a performance boost compared to using Performance is somewhat slower than Thus I don't know if |
are you guys talking about streaming support here? I can't believe this package do not support streaming |
@pleerock yes, tangentally :) You can already make your own streams using the |
Sounds great I would like it to be part of official package functionality. Maybe instead of separate package you can provide a PR that author can accept. Why streaming should not be part of sqlite package? |
I agree that it is functionality that should be provided by the official package. When I started the conversation in this thread I was looking for architectural input from the maintainers and have not received any yet, so I won't put time into making a PR at this time. |
I would like a async iterator. for await (let row of db.each(query)) {
// code
}
// done you can be in control of requesting more data when needed if it would return a async generator class x {
async * [Symbol.asyncIterator]() {
while (have_more) {
yield await get_next
}
}
async [Symbol.iterator]() {
return this.values()
}
async * values() {
return result_array.values()
}
} |
You can make a wrapper with a generator that uses db.each to do this… Note
that node-sqlite can't stop the .each call.
I use a different approach: I use a wrapper that does a LIMIT 100 .all()
and then processes those results and then it repeats until it processed all
data. It is not atomic but I don't need it to be in my case.
https://github.com/StratoKit/strato-db/blob/28c9ef581074e249e050840fa1dc5960be7c88ed/src/JsonModel/JsonModel.js#L644-L650
… |
I came across the same scenario where I need to fetch large number of rows and went with db#each. Later I understood, it still accumulated rows and gave the same result of using db#all performance wise. After spending some time on exploration and experiments, I found a work around using statement#get. Prepare the statement and call stmt#get, to retrieve a row, once the callback is executed, call stmt#get which gives the next row. Perform this in loop until it returns undefined (marks end of result). Of course, this is much slower than db#all & db#each but it saves your code from crash due to out of memory exception especially when dealing with large data. |
@sujatha97714 if this is a problem for you, you'd be better off with better-sqlite. It will be way faster, but it's not async. |
I want to handle 10,000,000 rows.
Each row will take 1 second to complete.
I have two question:
node-sqlite3
load all queries into memory, or it use stream/pipe from hard-disk row after row, every time thecallback
is called?callback
. When there are some async tasks, it needs to wait until the task if finished:by the way, Congratulations::
I have permissions, and created new
node-sqlite3
tag in StackOverflow:http://stackoverflow.com/questions/tagged/node-sqlite3
The text was updated successfully, but these errors were encountered: