8

在执行了现有 posgresql 模式的 pg_dump 之后,我有一个 sql 文件,其中包含许多使用副本的表填充语句。

COPY test_table (id, itm, factor, created_timestamp, updated_timestamp, updated_by_user, version) FROM stdin;
1   600 0.000   2012-07-17 18:12:42.360828  2012-07-17 18:12:42.360828  system  0
2   700 0.000   2012-07-17 18:12:42.360828  2012-07-17 18:12:42.360828  system  0
\.

虽然不是标准的,但这是 PostgreSQL 的 PLSQL 实现的一部分。

执行 flyway 迁移(通过 maven 插件)我得到:

[ERROR] Caused by org.postgresql.util.PSQLException: ERROR: unexpected message type 0x50 during COPY from stein

我做错了什么,还是不支持?

谢谢。

4

2 回答 2

7

简短的回答是否定的。

一个明确的问题是解析器当前无法处理这种特殊结构。

另一个问题是jdbc 驱动程序支持。您能否尝试通过单个 createStatement 调用查看 jdbc 驱动程序是否普遍支持此语法?

如果是,请在问题跟踪器中提交问题,我将扩展解析器。

更新:现在支持

于 2012-07-18T09:15:27.467 回答
2

我已经使用 Postgres 完成了这个

public abstract class SeedData implements JdbcMigration {

    protected static final String CSV_COPY_STRING = "COPY %s(%s) FROM STDIN HEADER DELIMITER ',' CSV ENCODING 'UTF-8'";

    protected CopyManager copyManager;

    @Override
    public void migrate(Connection connection) throws Exception {
        log.info(String.format("[%s] Populating database with seed data", getClass().getName()));
        copyManager = new CopyManager((BaseConnection) connection);

        Resource[] resources = scanForResources();

        List<Resource> res = Arrays.asList(resources);
        for (Resource resource : res) {
            load(resource);
        }
    }

    private void load(Resource resource) throws SQLException, IOException {
        String location = resource.getLocation();

        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(location);
        if (inputStream == null) {
            throw new FlywayException("Failure to load seed data. Unable to load from location: " + location);
        }
        if (!inputStream.markSupported()) {
            // Sanity check. We have to be able to mark the stream.
            throw new FlywayException(
                    "Failure to load seed data as mark is not supported. Unable to load from location: " + location);
        }
        // set our mark to something big
        inputStream.mark(1 << 32);

        String filename = resource.getFilename();
        // Strip the prefix (e.g. 01_) and the file extension (e.g. .csv)
        String table = filename.substring(3, filename.length() - 4);
        String columns = loadCsvHeader(location, inputStream);

        // reset to the mark
        inputStream.reset();

        // Use Postgres COPY command to bring it in
        long result = copyManager.copyIn(String.format(CSV_COPY_STRING, table, columns), inputStream);
        log.info(format("   %s - Inserted %d rows", location, result));
    }

    private String loadCsvHeader(String location, InputStream inputStream) {
        try {
            return new BufferedReader(new InputStreamReader(inputStream)).readLine();
        } catch (IOException e) {
            throw new FlywayException("Failure to load seed data. Unable to load from location: " + location, e);
        }
    }

    private Resource[] scanForResources() throws IOException {
        return new ClassPathScanner(getClass().getClassLoader()).scanForResources(getSeedDataLocation(), "", ".csv");
    }

    protected String getSeedDataLocation() {
        return getClass().getPackage().getName().replace('.', '/');
    }

}

使用适当的类路径实现类

package db.devSeedData.dev;

public class v0_90__seed extends db.devSeedData.v0_90__seed {
}

所需要做的就是在 db/devSeedData 下的类路径中包含格式为 01_tablename.csv 的 CSV 文件。列是从 CSV 的标题行中提取的。

于 2015-06-19T15:51:47.593 回答