Как создать макет базы данных из CSV-файлов для JOOQ? - PullRequest
0 голосов
/ 09 июня 2019

Я прочитал следующие статьи и попытался загрузить данные из csv для создания фиктивной базы данных.

https://blog.jooq.org/tag/mock-data/

https://www.jooq.org/doc/3.11/manual/sql-execution/importing/importing-csv/

Но заканчивается следующими исключениями.

подробности ошибки:

org.jooq.exception.DataAccessException: SQL [insert into `database_name`.`table_name` (`id`, `epoch_time`) values (?, ?)]; Invalid SQL: insert into `database_name`.`table_name` (`id`, `epoch_time`) values (?, ?)

Количество обработанных строк: 1

Количество сохраненных строк (INSERT или UPDATE): 0

Количество пропущенных строк (из-за ошибок или повторяющегося правила): 1

Query query = error.query ();

System.out.println (query.getSQL ());

insert into `database_name`.`table_name` (`id`, `epoch_time`) values (?, ?)

System.out.println (query.getBindValues ​​()); * * тысяча двадцать семь

[50331, 1556686800]

System.out.println (query.getParams ());

{1=50331, 2=1556686800}

Вопрос

Мое понимание Jooq не велико.

  1. Значения не связаны в SQL выше?

  2. Я не уверен, как добавить функциональность загрузки файлов CSV в коде ниже. CSV Loader возвращает Loader<Record>, где для MockResult требуется Result<Record>.

    @Override
    public MockResult[] execute(MockExecuteContext context) 
    throws SQLException {
    
    // Use ordinary jOOQ API to create an org.jooq.Result object.
    // You can also use ordinary jOOQ API to load CSV files or
    // other formats, here!
    DSLContext create = DSL.using(configuration);
    Result<MyTableRecord> result = create.newResult(MY_TABLE);
    result.add(create.newRecord(MY_TABLE));
    
    // Now, return 1-many results, depending on whether this is
    // a batch/multi-result context
    return new MockResult[] {
        new MockResult(1, result)
        };
    }
    

1 Ответ

0 голосов
/ 10 июня 2019

Хорошо, у меня все было не так.

У меня сложилось впечатление, что вы можете загружать данные в таблицы в памяти, используя приведенный ниже API, и создавать фиктивную базу данных, состоящую из нескольких обязательных таблиц, и выполнять некоторые запросы к ней.

// Load data into the BOOK table from an input stream
// holding the CSV data.
create.loadInto(BOOK)
      .loadCSV(inputstream, encoding)
      .fields(BOOK.ID, BOOK.AUTHOR_ID, BOOK.TITLE)
      .execute();

Поняв, что потратив пару часов на выяснение того, как загрузить данные из csv (описано ниже), jooq (удивительный API для написания запросов) не является ядром базы данных и не может на самом деле выполняться запросы к данным в памяти.

загрузка фиктивных данных из csv:

@Override
public MockResult[] execute(MockExecuteContext ctx) throws SQLException {


    List<String> strings = Files.readAllLines(Paths.get("table_data.csv"));
    String csvString = strings.stream()
            .reduce(new StringJoiner("\n"), StringJoiner::add, StringJoiner::merge)
            .toString();

    DSLContext create = DSL.using(SQLDialect.MYSQL);

    Result<Record> records = create.fetchFromCSV(csvString);
    List<YourTableDataRecord> tableDataList = records.into(YourTableDataRecord.class);

    Result<YourTableDataRecord> result = create.newResult(POJO_RERESENTING_THE_DATA);

    result.addAll(tableDataList);

    return new MockResult[]{
            new MockResult(result.size(), result)
    };
}

Обратите внимание, что вышеупомянутое решение может быть сделано более эффективно, читая построчно и кэшируя результаты.

Кроме того, для каждого запроса должен быть создан фиктивный результат. Подробнее читайте здесь https://blog.jooq.org/tag/unit-testing/ в разделе Для этого используйте MockDataProvider от jOOQ

...