2017-02-07 15 views
0

Я использую Groovy Sql.withBatch для обработки CSV-файла и загрузки всех данных в моем почтовом ящике Postgres.Groovy Sql WithBatch отсутствует записи в БД

Вот мой метод:

def processCSV() { 
    def logger = Logger.getLogger('groovy.sql') 
    logger.level = Level.FINE 
    logger.addHandler(new ConsoleHandler(level: Level.FINE)) 

    def fileName = "file.csv" 
    def resource = this.getClass().getResource('/csv/' + fileName) 

    File file = new File(resource.path) 

    String year = '2016' 

    char separator = ',' 

    def lines = CSV 
      .separator(separator) 
      .skipLines(1) 
      .quote(CSVParser.DEFAULT_QUOTE_CHARACTER) 
      .escape(CSVParser.DEFAULT_ESCAPE_CHARACTER) 
      .charset('UTF-8') 
      .create() 
      .reader(file) 
      .readAll() 

    def totalLines = lines.size() 

    Sql sql = getDatabaseInstance() 

    println("Delete existing rows for " + year + " if exists") 
    String dQuery = "DELETE FROM table1 WHERE year = ?" 
    sql.execute(dQuery, [year]) 

    def statement = 'INSERT INTO table1 (column1, column2, column3, coulmn4, year) VALUES (?, ?, ?, ?, ?)' 

    println("Total lines in the CSV files: " + totalLines) 

    def batches = [] 

    sql.withBatch(BATCH_SIZE, statement) { ps -> 
     lines.each { fields -> 
      String coulmn1 = fields[0] 
      String coulmn2 = fields[1] 
      String column3 = fields[2] 
      String column4 = fields[3] 

      def params = [column1, coulmn2, column3, column4, year] 

      def batch = ['params': params, 'error': false] 
      try { 
       ps.addBatch(params) 
      } 
      catch (all) { 
       batch['error'] = true 
       throw all 
      } 

      batches << batch 
     } 
    } 

    def recordsAddedInDB = sql.firstRow("SELECT count(*) FROM " + tableName + " WHERE year = ?", year)[0] 

    sql.close() 

    println("") 
    println("Processed lines: " + line) 
    println("Batches: " + batches.size()) 
    println("Batches in error: " + batches.findAll{ it.error }.size()) 
    println("Record in DB for " + year + ": " + recordsAddedInDB) 
} 

Строки в файлах CSV (exclusing строку заголовка) являются 23758. Выход этого метода заключается в следующем:

Delete existing rows for 2016 if exists 
Total lines in the CSV files: 23758 
Processed lines: 23758 
Batches: 23758 
Batches in error: 0 
Record in DB for 2016 year: 23580 

Если включить каротаж, с BATCH_SIZE 500, я могу видеть:

  • 47 раз, предложение «Успешно LY выполняется пакет 500 команд (ы)»
  • 1 раз приговор„успешно выполнил партию с 258 команд (ы)“

Что означает 23758 вставки заявление было обработано.

У кого-нибудь есть идея, почему количество строк в базе данных меньше, чем обработанных?

+0

Только для судебной экспертизы exatra: возможно, стоит посмотреть на возвращаемое значение из sql.withBatch, например 'def counts = sql.withBatch {} .sum()'. Также может быть полезно добавить 'ps.executeBatch()' непосредственно после ps.addBatch, чтобы узнать, что вы получаете. –

+0

sql.withBatch {} .sum() возвращает 23580 ... то же количество записей, которые у меня есть в базе данных. Если я добавлю ps.executeBatch(), то каждый оператор insert выполняется один, sql.withBatch {} .sum() возвращает 0, а в базе данных у меня все равно такое же количество записей. – Bagbyte

+0

Если у вас есть повторяющиеся значения для столбцов id в ваших indata? т. е. вы можете вставлять идентичные строки, которые будут перезаписывать друг друга в базе данных. –

ответ

0

Решено. Оператор INSERT имеет подзапрос, когда подзапрос не возвращает значение, инструкция INSERT игнорируется.