flyway迁移是否支持PostgreSQL的COPY?

时间:2012-07-17 17:33:00

标签: database postgresql flyway

执行了现有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实现的一部分。

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

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

我做错了什么,或者这只是不支持?

感谢。

2 个答案:

答案 0 :(得分:5)

简短的回答是

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

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

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

更新:现在支持

答案 1 :(得分: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的标题行中提取。