Подтвердить что ты не робот

Использование chardet для обнаружения плохой кодировки в MySQL db с помощью JDBC

Недавно мы перенесли наш mysql db из Latin1 в UTF8. Попробовав несколько разных подходов к его конвертированию, мы не смогли найти ни одного, который также не представил бы довольно неприятный dataloss (и многие просто ничего не делали).

Это заставило меня подумать, есть ли у нас много разных кодировок, потому что, похоже, не существует единого подхода, который охватывает наши тестовые примеры (различные записи в нашей базе данных). Чтобы проверить эту теорию, я написал небольшое приложение scala (во-первых, не стесняйтесь смеяться над тем, насколько мощным и неидиоматичным оно является: D), который использовал chardet, чтобы посмотреть на сообщения и сказать мне кодировку.

Только одна проблема, все всегда UTF8.

Здесь код:

package main.scala

import org.mozilla.universalchardet.UniversalDetector
import java.sql.DriverManager

object DBConvert {
  def main(args: Array[String]) {
    val detector = new UniversalDetector(null)
    val db_conn_str = "jdbc:mysql://localhost:3306/mt_pre?user=root"
    val connection = DriverManager.getConnection(db_conn_str)

    try {
        val statement = connection.createStatement()
        val rs = statement.executeQuery("SELECT * FROM mt_entry where entry_id = 3886")
        while (rs.next) {
           val buffer = rs.getBytes("entry_text_more")
           detector.handleData(buffer, 0, buffer.length)
           detector.dataEnd()

           val encoding:String = detector.getDetectedCharset;

           if (encoding != null) println("Detected encoding = " + encoding) else println("No encoding detected.");

           detector.reset();

           // Just so we can see the output
           println(rs.getString("entry_text_more"))
        }
    } catch {
      case _ => e: Exception => println(e.getMessage)
    }
    finally {
        connection.close()
    }
  }
}

Я попытался передать useUnicode строку запроса JDBC, также characterEncoding. Ни один из них не сдвинулся с места, когда UTF-8 всегда выходил. Также попытался использовать getBinaryStream и другие, еще UTF-8.

Полностью признаем, что кодировка символов заставляет мою голову немного сгибаться, а игра с новым языком может быть не лучшим способом решить эту проблему.:) Сказано, что мне интересно - есть ли способ захватить данные из db и определить, какая кодировка была помещена туда, или это одна из тех вещей, которые просто так кодируются как UTF-8 в БД, независимо от того, как вы его извлекаете, что именно это (забавные персонажи и все)?

Спасибо!

4b9b3361

Ответ 1

Как-то у меня была аналогичная проблема. См. Этот ответ. Установка кодировки внутри строки подключения может помочь.

Ответ 2

Обратите внимание, что таблица Charset и Charset Connection и кодировка базы данных по умолчанию - все те же UTF-8. У меня был один экземпляр, в котором Datbases default был UTF-8, но таблицы coloumns были все еще латыни, поэтому у меня была проблема. Посмотрите, если это так.