如何使用 apache 元模型将数据插入 csv 文件?
how to insert data into csv file using apche meta model?
我在 java 项目中工作,我正在使用 apache 元模型将数据插入 csv 文件。
代码:
public void insertIntoCSVFile(){
File myFile = new File("unexisting_file.csv");
UpdateableDataContext dataContext = DataContextFactory.createCsvDataContext(myFile);
final Schema schema = dataContext.getDefaultSchema();
dataContext.executeUpdate(new UpdateScript() {
public void run(UpdateCallback callback) {
// CREATING A TABLE
Table table = callback.createTable(schema, "my_table")
.withColumn("name").ofType(VARCHAR)
.withColumn("gender").ofType(CHAR)
.withColumn("age").ofType(INTEGER)
.execute();
// INSERTING SOME ROWS
callback.insertInto(table).value("name","John Doe").value("gender",'M').value("age",42).execute();
callback.insertInto(table).value("name","Jane Doe").value("gender",'F').value("age",42).execute();
}
});
}
每当我为同一个 csv 文件调用此方法时,它都会成功插入数据,但会删除旧数据,然后插入新数据,因此每次只插入两行。
我想通过多次调用函数来插入多个重复行,这意味着新行应该追加而旧行保持不变。
我怎样才能做到这一点?
将 table 创建代码移到数据插入方法之外。每次在 CSV 文件中创建 table,它都会覆盖之前的 table 及其内容。
这是一种方法:
import java.io.File;
import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.DataContextFactory;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.schema.ColumnType;
public class App {
public static void main(String[] args) {
File myFile = new File("c:/tmp/unexisting_file.csv");
UpdateableDataContext dataContext = DataContextFactory.createCsvDataContext(myFile);
final Schema schema = dataContext.getDefaultSchema();
final String tableName = "my_table";
dataContext.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
// CREATING A TABLE
Table table = callback.createTable(schema, tableName)
.withColumn("name").ofType(ColumnType.VARCHAR)
.withColumn("gender").ofType(ColumnType.CHAR)
.withColumn("age").ofType(ColumnType.INTEGER)
.execute();
}
});
insertIntoCSVFile(dataContext, tableName);
insertIntoCSVFile(dataContext, tableName);
}
public static void insertIntoCSVFile(final UpdateableDataContext dataContext,
final String tableName) {
dataContext.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
String schemaName = dataContext.getDefaultSchema().getName();
Table table = dataContext.getTableByQualifiedLabel(schemaName + "." + tableName);
// INSERTING SOME ROWS
callback.insertInto(table).value("name", "John Doe").value("gender", 'M').value("age", 42).execute();
callback.insertInto(table).value("name", "Jane Doe").value("gender", 'F').value("age", 42).execute();
}
});
}
}
在这个例子中,main方法负责创建table。然后这个方法调用两次数据插入方法,传入相关上下文和table name.
生成的文件内容为:
"name","gender","age"
"John Doe","M","42"
"Jane Doe","F","42"
"John Doe","M","42"
"Jane Doe","F","42"
有关详细信息,请参阅 creation of tables in CSV files 的语义 - 特别是:
Create or overwrite the CSV file with a (new) table structure.
更新
您可以通过检查 table 是否已经存在来防止数据被覆盖,然后再尝试创建它。
这是一个展示该方法的简单示例:
首先,更改 table 名称,使其与文件名匹配:
final String tableName = "unexisting_file.csv";
这是因为 MetaModel 使用此作为 CSV 文件中 table 的默认 table 名称。我们可以用它来检查我们是否已经创建了 table:
if (!tableExists()) {
createTable();
}
使用上述方法,这里是一个完整的例子:
import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.csv.CsvConfiguration;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.util.Resource;
import org.apache.metamodel.util.FileResource;
public class CsvDemo {
private final String tableName;
private final UpdateableDataContext dataContext;
public CsvDemo() {
this.tableName = "example.csv";
Resource resource = new FileResource("c:/tmp/" + tableName);
CsvConfiguration configuration = new CsvConfiguration();
this.dataContext = new CsvDataContext(resource, configuration);
}
public void doWork() {
if (!tableExists()) {
createTable();
}
appendData();
}
private boolean tableExists() {
return getTable() != null;
}
private Table getTable() {
return dataContext.getDefaultSchema().getTableByName(tableName);
}
private void createTable() {
dataContext.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
callback.createTable(dataContext.getDefaultSchema(), tableName)
.withColumn("name").ofType(ColumnType.VARCHAR)
.withColumn("gender").ofType(ColumnType.CHAR)
.withColumn("age").ofType(ColumnType.INTEGER)
.execute();
}
});
}
private void appendData() {
dataContext.executeUpdate(new UpdateScript() {
final Table table = getTable();
@Override
public void run(UpdateCallback callback) {
callback.insertInto(table).value("name", "John Doe")
.value("gender", 'M').value("age", 42).execute();
callback.insertInto(table).value("name", "Jane Doe")
.value("gender", 'F').value("age", 42).execute();
}
});
}
}
现在,如果 table 不存在,您将只在 CSV 文件中创建它。如果它确实存在,那么您的附加数据将附加到文件中已有的任何数据。
我在 java 项目中工作,我正在使用 apache 元模型将数据插入 csv 文件。
代码:
public void insertIntoCSVFile(){
File myFile = new File("unexisting_file.csv");
UpdateableDataContext dataContext = DataContextFactory.createCsvDataContext(myFile);
final Schema schema = dataContext.getDefaultSchema();
dataContext.executeUpdate(new UpdateScript() {
public void run(UpdateCallback callback) {
// CREATING A TABLE
Table table = callback.createTable(schema, "my_table")
.withColumn("name").ofType(VARCHAR)
.withColumn("gender").ofType(CHAR)
.withColumn("age").ofType(INTEGER)
.execute();
// INSERTING SOME ROWS
callback.insertInto(table).value("name","John Doe").value("gender",'M').value("age",42).execute();
callback.insertInto(table).value("name","Jane Doe").value("gender",'F').value("age",42).execute();
}
});
}
每当我为同一个 csv 文件调用此方法时,它都会成功插入数据,但会删除旧数据,然后插入新数据,因此每次只插入两行。
我想通过多次调用函数来插入多个重复行,这意味着新行应该追加而旧行保持不变。
我怎样才能做到这一点?
将 table 创建代码移到数据插入方法之外。每次在 CSV 文件中创建 table,它都会覆盖之前的 table 及其内容。
这是一种方法:
import java.io.File;
import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.DataContextFactory;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.schema.ColumnType;
public class App {
public static void main(String[] args) {
File myFile = new File("c:/tmp/unexisting_file.csv");
UpdateableDataContext dataContext = DataContextFactory.createCsvDataContext(myFile);
final Schema schema = dataContext.getDefaultSchema();
final String tableName = "my_table";
dataContext.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
// CREATING A TABLE
Table table = callback.createTable(schema, tableName)
.withColumn("name").ofType(ColumnType.VARCHAR)
.withColumn("gender").ofType(ColumnType.CHAR)
.withColumn("age").ofType(ColumnType.INTEGER)
.execute();
}
});
insertIntoCSVFile(dataContext, tableName);
insertIntoCSVFile(dataContext, tableName);
}
public static void insertIntoCSVFile(final UpdateableDataContext dataContext,
final String tableName) {
dataContext.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
String schemaName = dataContext.getDefaultSchema().getName();
Table table = dataContext.getTableByQualifiedLabel(schemaName + "." + tableName);
// INSERTING SOME ROWS
callback.insertInto(table).value("name", "John Doe").value("gender", 'M').value("age", 42).execute();
callback.insertInto(table).value("name", "Jane Doe").value("gender", 'F').value("age", 42).execute();
}
});
}
}
在这个例子中,main方法负责创建table。然后这个方法调用两次数据插入方法,传入相关上下文和table name.
生成的文件内容为:
"name","gender","age"
"John Doe","M","42"
"Jane Doe","F","42"
"John Doe","M","42"
"Jane Doe","F","42"
有关详细信息,请参阅 creation of tables in CSV files 的语义 - 特别是:
Create or overwrite the CSV file with a (new) table structure.
更新
您可以通过检查 table 是否已经存在来防止数据被覆盖,然后再尝试创建它。
这是一个展示该方法的简单示例:
首先,更改 table 名称,使其与文件名匹配:
final String tableName = "unexisting_file.csv";
这是因为 MetaModel 使用此作为 CSV 文件中 table 的默认 table 名称。我们可以用它来检查我们是否已经创建了 table:
if (!tableExists()) {
createTable();
}
使用上述方法,这里是一个完整的例子:
import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.csv.CsvConfiguration;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.util.Resource;
import org.apache.metamodel.util.FileResource;
public class CsvDemo {
private final String tableName;
private final UpdateableDataContext dataContext;
public CsvDemo() {
this.tableName = "example.csv";
Resource resource = new FileResource("c:/tmp/" + tableName);
CsvConfiguration configuration = new CsvConfiguration();
this.dataContext = new CsvDataContext(resource, configuration);
}
public void doWork() {
if (!tableExists()) {
createTable();
}
appendData();
}
private boolean tableExists() {
return getTable() != null;
}
private Table getTable() {
return dataContext.getDefaultSchema().getTableByName(tableName);
}
private void createTable() {
dataContext.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
callback.createTable(dataContext.getDefaultSchema(), tableName)
.withColumn("name").ofType(ColumnType.VARCHAR)
.withColumn("gender").ofType(ColumnType.CHAR)
.withColumn("age").ofType(ColumnType.INTEGER)
.execute();
}
});
}
private void appendData() {
dataContext.executeUpdate(new UpdateScript() {
final Table table = getTable();
@Override
public void run(UpdateCallback callback) {
callback.insertInto(table).value("name", "John Doe")
.value("gender", 'M').value("age", 42).execute();
callback.insertInto(table).value("name", "Jane Doe")
.value("gender", 'F').value("age", 42).execute();
}
});
}
}
现在,如果 table 不存在,您将只在 CSV 文件中创建它。如果它确实存在,那么您的附加数据将附加到文件中已有的任何数据。