如何使用Java中的数据库运行PDI转换?
我正在尝试从Java运行一个涉及数据库(任何数据库,但noSQL数据库更为可取)的PDI转换 我试过使用mongodb和cassandradb,但缺少插件,我已经在这里问过了:,但还没有人回答 我也尝试过使用PostgreSQL切换到SQL DB,但仍然不起作用。从我所做的研究来看,我认为这是因为我没有完全从Java连接数据库,但我还没有找到任何适合我的教程或方向。我试着按照这个博客中的说明去做::但仍然有一些关于存储库的问题(因为我没有,而且似乎需要) 当我从Spoon运行它时,转换很好。当我从Java运行它时,它才失败 谁能帮助我如何运行涉及数据库的PDI转换?我哪里出错了 是否有人成功地从noSQL和SQL数据库运行PDI转换?你用了什么数据库如何使用Java中的数据库运行PDI转换?,java,database,pentaho,kettle,pdi,Java,Database,Pentaho,Kettle,Pdi,我正在尝试从Java运行一个涉及数据库(任何数据库,但noSQL数据库更为可取)的PDI转换 我试过使用mongodb和cassandradb,但缺少插件,我已经在这里问过了:,但还没有人回答 我也尝试过使用PostgreSQL切换到SQL DB,但仍然不起作用。从我所做的研究来看,我认为这是因为我没有完全从Java连接数据库,但我还没有找到任何适合我的教程或方向。我试着按照这个博客中的说明去做::但仍然有一些关于存储库的问题(因为我没有,而且似乎需要) 当我从Spoon运行它时,转换很好。当我
如果我问了太多问题,我很抱歉,我太绝望了。任何类型的信息都将不胜感激。谢谢。从Java执行PDI作业非常简单。您只需要导入所有必需的jar文件(用于数据库),然后调用kettle类。显然,最好的方法是使用“Maven”来控制依赖关系。在maven
pom.xml
文件中,只需调用数据库驱动程序
假设您使用pentaho v5.0.0GA和数据库作为PostgreSQL,Maven文件示例如下:
<dependencies>
<!-- Pentaho Kettle Core dependencies development -->
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-core</artifactId>
<version>5.0.0.1</version>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-dbdialog</artifactId>
<version>5.0.0.1</version>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-engine</artifactId>
<version>5.0.0.1</version>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-ui-swt</artifactId>
<version>5.0.0.1</version>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle5-log4j-plugin</artifactId>
<version>5.0.0.1</version>
</dependency>
<!-- The database dependency files. Use it if your kettle file involves database connectivity. -->
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-902.jdbc4</version>
</dependency>
五氢水壶
. 它适用于数据库连接
希望这有帮助:)
- 我用“没有jndi的转换”尝试了你的代码,效果很好李>
但我需要在pom.xml中添加此存储库:
<repositories>
<repository>
<id>pentaho-releases</id>
<url>http://repository.pentaho.org/artifactory/repo/</url>
</repository>
</repositories>
有一种非专业化:
if (simpleJndi) {
JndiUtil.initJNDI();
}
在JndiUtil中:
String path = Const.JNDI_DIRECTORY;
if ((path == null) || (path.equals("")))
在常量类中:
public static String JNDI_DIRECTORY = NVL(System.getProperty("KETTLE_JNDI_ROOT"), System.getProperty("org.osjava.sj.root"));
所以我们需要设置这个变量cattle\u JNDI\u ROOT
[FIX]示例中的一个小改动:只需添加以下内容
System.setProperty("KETTLE_JNDI_ROOT", jdbcPropertiesPath);
以前
KettleEnvironment.init();
基于代码的完整示例:
import java.io.File;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
public class ExecuteSimpleTransformationWithJndiDatasource {
public static void main(String[] args) {
String resourcesPath = (new File(".").getAbsolutePath())+"\\src\\main\\resources";
String ktr_path = resourcesPath+"\\transformation_with_jndi.ktr";
//KETTLE_JNDI_ROOT could be the simple-jndi folder in your pdi or spoon home.
//in this example, is the resources folder
String jdbcPropertiesPath = resourcesPath;
try {
/**
* Initialize the Kettle Enviornment
*/
System.setProperty("KETTLE_JNDI_ROOT", jdbcPropertiesPath);
KettleEnvironment.init();
/**
* Create a trans object to properly assign the ktr metadata.
*
* @filedb: The ktr file path to be executed.
*
*/
TransMeta metadata = new TransMeta(ktr_path);
Trans trans = new Trans(metadata);
// Execute the transformation
trans.execute(null);
trans.waitUntilFinished();
// checking for errors
if (trans.getErrors() > 0) {
System.out.println("Erroruting Transformation");
}
} catch (KettleException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
有关完整示例,请查看my github频道:
我在使用pentaho库的应用程序中遇到了同样的问题。我解决了此代码的问题:
singleton到init釜:
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.exception.KettleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Inicia as configurações das variáveis de ambiente do kettle
*
* @author Marcos Souza
* @version 1.0
*
*/
public class AtomInitKettle {
private static final Logger LOGGER = LoggerFactory.getLogger(AtomInitKettle.class);
private AtomInitKettle() throws KettleException {
try {
LOGGER.info("Iniciando kettle");
KettleJNDI.protectSystemProperty();
KettleEnvironment.init();
LOGGER.info("Kettle iniciado com sucesso");
} catch (Exception e) {
LOGGER.error("Message: {} Cause {} ", e.getMessage(), e.getCause());
}
}
}
还有救我的代码:
import java.io.File;
import java.util.Properties;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.exception.KettleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KettleJNDI {
private static final Logger LOGGER = LoggerFactory.getLogger(KettleJNDI.class);
public static final String SYS_PROP_IC = "java.naming.factory.initial";
private static boolean init = false;
private KettleJNDI() {
}
public static void initJNDI() throws KettleException {
String path = Const.JNDI_DIRECTORY;
LOGGER.info("Kettle Const.JNDI_DIRECTORY= {}", path);
if (path == null || path.equals("")) {
try {
File file = new File("simple-jndi");
path = file.getCanonicalPath();
} catch (Exception e) {
throw new KettleException("Error initializing JNDI", e);
}
Const.JNDI_DIRECTORY = path;
LOGGER.info("Kettle null > Const.JNDI_DIRECTORY= {}", path);
}
System.setProperty("java.naming.factory.initial", "org.osjava.sj.SimpleContextFactory");
System.setProperty("org.osjava.sj.root", path);
System.setProperty("org.osjava.sj.delimiter", "/");
}
public static void protectSystemProperty() {
if (init) {
return;
}
System.setProperties(new ProtectionProperties(SYS_PROP_IC, System.getProperties()));
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Kettle System Property Protector: System.properties replaced by custom properies handler");
}
init = true;
}
public static class ProtectionProperties extends Properties {
private static final long serialVersionUID = 1L;
private final String protectedKey;
public ProtectionProperties(String protectedKey, Properties prprts) {
super(prprts);
if (protectedKey == null) {
throw new IllegalArgumentException("Properties protection was provided a null key");
}
this.protectedKey = protectedKey;
}
@Override
public synchronized Object setProperty(String key, String value) {
// We forbid changes in general, but do it silent ...
if (protectedKey.equals(key)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Kettle System Property Protector: Protected change to '" + key + "' with value '" + value + "'");
}
return super.getProperty(protectedKey);
}
return super.setProperty(key, value);
}
}
}
我认为你们的问题在于数据库的连接。您可以在转换中进行配置,而不需要使用JNDI
public class DatabaseMetaStep {
private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseMetaStep.class);
/**
* Adds the configurations of access to the database
*
* @return
*/
public static DatabaseMeta createDatabaseMeta() {
DatabaseMeta databaseMeta = new DatabaseMeta();
LOGGER.info("Carregando informacoes de acesso");
databaseMeta.setHostname("localhost");
databaseMeta.setName("stepName");
databaseMeta.setUsername("user");
databaseMeta.setPassword("password");
databaseMeta.setDBPort("port");
databaseMeta.setDBName("database");
databaseMeta.setDatabaseType("MonetDB"); // sql, MySql ...
databaseMeta.setAccessType(DatabaseMeta.TYPE_ACCESS_NATIVE);
return databaseMeta;
}
}
然后您需要将databaseMeta设置为Transmeta
DatabaseMeta databaseMeta = DatabaseMetaStep.createDatabaseMeta();
TransMeta transMeta = new TransMeta();
transMeta.setUsingUniqueConnections(true);
transMeta.setName("ransmetaNeame");
List<DatabaseMeta> databases = new ArrayList<>();
databases.add(databaseMeta);
transMeta.setDatabases(databases);
DatabaseMeta-DatabaseMeta=DatabaseMetaStep.createDatabaseMeta();
TransMeta TransMeta=新TransMeta();
transMeta.setUsingUniqueConnections(真);
transMeta.setName(“transmetaneame”);
List databases=new ArrayList();
添加(databaseMeta);
transMeta.setDatabases(数据库);
如果从Java运行,会出现什么样的错误(提供堆栈跟踪)?您确定postgres主机可访问且postgresql已启动并运行吗?Postgresql jdbc驱动程序是否可用(在u java程序的类路径中)?你确定postgresql驱动程序、jvm和postgres it本身之间的版本匹配吗?是的,我确定,我尝试过执行一个简单的查询,结果很好。但我不确定版本,如何检查?我得到的错误是“初始化表输出失败”,在这里您可以找到包含所有jdbc驱动程序的表,以及有关兼容jdk版本、postgres版本的信息。Pentaho最新JDK7兼容。感谢您的回复,您可以添加您的转换截图吗?所以我们不需要设置DatabaseMeta或者我之前提到的任何东西?事实上,当不涉及数据库时,我的转换做得很好。然后我得到错误“初始化步骤失败:表输出”检查这个git-hub-repo:我已经附加了整个代码。它也可以在上面的博客链接中找到。
public class DatabaseMetaStep {
private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseMetaStep.class);
/**
* Adds the configurations of access to the database
*
* @return
*/
public static DatabaseMeta createDatabaseMeta() {
DatabaseMeta databaseMeta = new DatabaseMeta();
LOGGER.info("Carregando informacoes de acesso");
databaseMeta.setHostname("localhost");
databaseMeta.setName("stepName");
databaseMeta.setUsername("user");
databaseMeta.setPassword("password");
databaseMeta.setDBPort("port");
databaseMeta.setDBName("database");
databaseMeta.setDatabaseType("MonetDB"); // sql, MySql ...
databaseMeta.setAccessType(DatabaseMeta.TYPE_ACCESS_NATIVE);
return databaseMeta;
}
}
DatabaseMeta databaseMeta = DatabaseMetaStep.createDatabaseMeta();
TransMeta transMeta = new TransMeta();
transMeta.setUsingUniqueConnections(true);
transMeta.setName("ransmetaNeame");
List<DatabaseMeta> databases = new ArrayList<>();
databases.add(databaseMeta);
transMeta.setDatabases(databases);