Search code examples
node.jstypescriptpromisetypeorm

Typeorm won't wait for no save


Been struggling with typeorm, and I may have gotten something on the back foot.

Writing a database initiation script (to then start using the data). Some of the files have up to a million records, there are some foreign keys in there, and there will be about five files that will be loaded backend to get the base sorted.

My problem is, how do I get typeorm to tell me when save is successful as if I just put await on save

                await profileRepository.save(EUprofile)

I get

"Error:(37, 17) TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules."

But if I don't use it, it continues the code as soon as the save instruction has been issued.

I can get around this by just opening a new connection for each write, await works, but then I run out of connections very quickly, but the await works, so instead I wrapped the whole file read in:

createConnection().then(async connection => {

Works, but can't use await so I don't know when anything have finished loading.

Full script:

import "reflect-metadata";
import {createConnection} from "typeorm";
import * as csvParser from "csv-parser";
import * as fs from "fs";


// Lets load the profiles
import {EUProfile} from "./config/EUProfile.entity";
import {EUUser} from "./config/EUUsers.entity";

// Lets open up the database
createConnection().then(async connection => {



// Lets set the standard input files
const profileFS:string = "./dbinitdata/ProfileIdName.csv";
const usersFS:string = "./dbinitdata/UserProfiles.csv";
var loadsRunning:number = 1;


    let readCount:number = 0;
    let saveCount:number = 0;

    let readStartDate:number = new Date().getTime();
    console.log("PROFILE: Starting load:" + profileFS + " at " + new Date(readStartDate));
    fs.createReadStream(profileFS)
        .pipe(csvParser())
        .on('data', (data) => {
            // Lets map it
            const EUprofile = new EUProfile();
            EUprofile.id = data.ID;
            EUprofile.profileName = data.NAME
            readCount++;

                const profileRepository = connection.getRepository(EUProfile);
                await profileRepository.save(EUprofile)
                saveCount++;
                if (saveCount == readCount ){
                    var commitTime:number = new Date().getTime()
                    console.log("PROFILE: Records commited to database: " + saveCount +" in " + new Date(commitTime - readStartDate).getMilliseconds() + " MS");
                    loadsRunning--;
                    if (loadsRunning == 0){
                        //console.log("Completed database init at " + new Date());
                        //process.exit();
                    }
                }


        })
        .on('end', () => {

            var readTime:number = new Date().getTime()
            console.log("PROFILE: Records Read from file: "+ readCount + " in " + new Date(readTime - readStartDate).getMilliseconds() + " MS");
    });
}).catch(error => console.log(error));

Database config (

{
  "name": "default",
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "node",
  "password": "NOTGONNATELLYOU",
  "database": "eu_stats",
  "synchronize": true,
  "logging": false,
  "entities": [
    "./config/*.entity.js"
  ],
  "migrations": [
    "config/migration/**/*.ts"
  ],
  "subscribers": [
    "config/subscriber/**/*.ts"
  ]
}

P.S. Should admit, this is my first attempt at writing a node app in Typescript, so sorry if I'm missing something obvious :)


Solution

  • You need to make the arrow function asynchronous by using async.

    Change this line:

    .on('data', (data) => {
    

    To this:

    .on('data', async (data) => {