chunk / big data / adonijs lucid big data / database cursor / adonis 에서 cursor 사용방법 / db query / size / big size / 쿼리 / node query / how to handle big query result
AdonisJS Lucid 에서 stream 사용
AdonisJS-lucid 의 사용에서 큰 결과 값을 갖는 query 를 다룰 때 stream 을 사용하면 된다. 일반적인 cursor 의 사용이라고 생각하면 될 듯 하다.
AdonisJS Lucid 의 문서에서는 찾기가 힘들었는데, community 에서 자료를 찾았다.(ref. 1)
내용을 정리하면, Lucid는 KnexJS 를 사용하고 있고, KnexJS 에서 streams 를 제공한다. 그것의 사용법은 아래와 같다.
아래 stream 의 예제는 ref. 1 을 참고해서 만들었다.
const ccursor =
Database.connection('cocktail')
.raw(
`SELECT * FROM point AS t1 WHERE t1.id !='tester'
ORDER BY id ASC`
).stream()
const prom = new Promise((resolve, reject)=>{
Logger.error('test2');
ccursor.on('data', (row)=>{
Logger.info('test-data');
})
ccursor.on('end', () => {
Logger.info('test-data');
resolve()
})
ccursor.on('error', (param1) => {
Logger.error('test-error : ' + param1);
reject()
})
});
await prom.then((val)=>{
Logger.info('test-resolve');
}).catch((val)=>{
Logger.error('test-reject');
});
위의 code 를 실행하면
Logger.info('test-data'); 가 계속 실행되다가 끝날때
Logger.info('test-data'); 가 실행될 것이다.
또는 아래처럼 작성해도 된다.
const prom = new Promise((resolve, reject)=>{
const ccursor =
Database.connection('cocktail')
.raw(
`SELECT * FROM g5_point AS t1 WHERE t1.mb_id !='admin'
ORDER BY po_id ASC`
).stream();
ccursor.on('data', (row)=>{
Logger.error('test-data');
})
ccursor.on('end', () => {
Logger.error('test-end');
resolve()
})
ccursor.on('error', (param1) => {
Logger.error('test-error : ' + param1);
reject()
})
});
await prom.then((val)=>{
Logger.error('test-resolve');
}).catch((val)=>{
Logger.error('test-reject');
});
async
아래처럼 async 를 사용할 수 있다.
const prom = new Promise(async (resolve, reject)=>{
const ccursor =
Database.connection('cocktail')
.raw(
`SELECT * FROM g5_point AS t1 WHERE t1.mb_id !='admin'
ORDER BY po_id ASC`
).stream();
ccursor.on('data', async (row)=>{
Logger.error('test-data');
})
ccursor.on('end', async () => {
Logger.error('test-end');
resolve()
})
ccursor.on('error', async (param1) => {
Logger.error('test-error : ' + param1);
reject()
})
});
await prom.then((val)=>{
Logger.error('test-resolve');
}).catch((val)=>{
Logger.error('test-reject');
});
아직은 사용하기가 쉽지 않다. 그리고 await/async 와 잘 맞지 않아 보인다. 그래서 자꾸 memory 가 넘치는 듯 하다.
개인적으로 현재로서는 그냥 offset, limit 을 이용해서 일정부분만 retrieve 해서 가져와서 사용하고, 다시 또 일정부분을 가져와서 사용하는 방식이 더 나아 보인다.
See Also
- laravel 에서 큰 Database result 를 처리할 때
References
- A Way to process large results of database Query in Adonis without consuming too much RAM - Help / Database - Forum - AdonisJS Framework
- Knex.js - A SQL Query Builder for Javascript