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実装の一部です。

(Mavenプラグインを介して)フライウェイの移行を実行すると、次のようになります。

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

私は何か間違ったことをしていますか、それともこれはサポートされていませんか?

ありがとう。

4

2 に答える 2

7

簡単な答えはノーです。

1つの明確な問題は、パーサーが現在この特別な構造を処理できないことです。

もう1つの質問は、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 {
}

必要なのは、01_tablename.csvの形式に従うdb/devSeedDataの下のクラスパスにCSVファイルを含めることだけです。列はCSVのヘッダー行から抽出されます。

于 2015-06-19T15:51:47.593 に答える