DynamoDB data to Redshift - amazon-dynamodb

I'm using Dynamo DB streams + Lamdba as trigger to invoke kinesis which puts my Dynamo DB data to Redshift.
Could someone suggest a way to load Dynamo DB data to Redshift in different regions using dynamo streams.

I had written one program that can move the data from Dynamo db to Redshift but that is not working without streams, You can take a look of code and see whether this helps your case or you get any Idea corresponding to this.
1.Creating the Connection with Redshift.
2.Create the Prepeared Statement for insertion into Redshift.
3.Fetching the data from Dynamo in batches using pagination.
4.Inserting the batch data into Resdhift in batches.
public void createConnectionWithRedshift() {
final String DB_URL = "jdbc:redshift://ao.cepuhmobd.us-west-2.redshift.amazonaws.com:5439/events";
// final String DB_URL = args[0];
// Database credentials
final String USER = "abc";
final String PASS = "abc";
Connection conn = null;
try {
// STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// createNewTable(conn);
// STEP 4: Execute a query
preparedStatement = conn.prepareStatement("insert into Events " + "(Vin,timestamp,eventtype,source,data)" + "VALUES (?,?,?,?,?)");
} catch (SQLException se) {
se.printStackTrace();
}
}// end main
public void replicateDynamoToRedshidt(int pages, int batchSize, int scanSize)
throws TableNeverTransitionedToStateException, InterruptedException {
createConnectionWithRedshift();//Redshift Connection
for (int i = 0; i < pages; i = i + 1) {
List<EventLogEntity> results = findAll(new PageRequest(i, batchSize));//Fetching the data from Dynamo in batches
List<HeadUnitData> headUnitDataList = headUnitEvents(results);
for (int j = 0; j < headUnitDataList.size(); j++) {
HeadUnitData headUnitData = headUnitDataList.get(j);
insertData(headUnitData.getVin(), headUnitData.getType(), headUnitData.getSource(), headUnitData.getData());//Inserting the data into Redshidt in batches
}
try {
preparedStatement.executeBatch();
System.out.println("Inserted in Database : " + results.size());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Related

can I backing up rocksdb while putting?

I want to back up rocksdb while not blocking my writing calls, the status I expected is rocksdb should back up the data at that moment and ignoring the writing calls while backing up, is there a proper way to accomplish this?
I tested this in java using rocksdb-jni:
RocksDB.loadLibrary();
RocksDB rocksDb = RocksDB.open("C:/rocksdb/data");
BackupEngine engine = BackupEngine.open(rocksDb.getEnv(), new BackupEngineOptions("C:/rocksdb/backup"));
for(int i = 0;i < 100000;i++){
byte[] k = ByteBuffer.allocate(4).putInt(0, i).array();
rocksDb.put(k,k);
}
ExecutorService executorService = Executors.newFixedThreadPool(2);
CountDownLatch countDownLatch = new CountDownLatch(1);
executorService.execute(() -> {
try {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
countDownLatch.await();
engine.createNewBackup(rocksDb, false);
} catch (RocksDBException | InterruptedException e) {
throw new RuntimeException(e);
}
});
executorService.execute(() -> {
try {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
countDownLatch.await();
//Thread.sleep(1);
for(int i = 100000;i < 200000;i++){
byte[] k = ByteBuffer.allocate(4).putInt(0, i).array();
rocksDb.put(k,k);
}
} catch (InterruptedException | RocksDBException e) {
throw new RuntimeException(e);
}
});
countDownLatch.countDown();
the result I expected from restoring is exactly 100000 records, but I always got more records
Yes - both backup and checkpoint engines can achieve this i.e. take a live backup while not blocking writes
https://github.com/facebook/rocksdb/wiki/How-to-backup-RocksDB

How to move Resultset curser via button click, and display data in textfields?

So, I'm creating a desktop banking application. It's nothing too serious, I'm just trying to practice and get better.
// Method I use to get a connection. I know this works.
public static Connection getConnection() throws SQLException {
String sCon = "jdbc:sqlite:banking.sqlite";
Connection connection = DriverManager.getConnection(sCon);
return connection;
}
.
..
...
.....Other code
Method I attempt to use to create and manipulate the data in the result set.
The problem I believe starts here. With this code, I am only able to return one row of the result set and only the last row.
public static Customers getAccounts(Customers c) {
String query = "select RowCount, Customers.Account_Number, "
+ "Customers.First_Name, Last_Name, Address, "
+ "Phone_Number, Accounts.Balance "
+ "from Customers "
+ "join Accounts ";
try (Connection connection = getConnection();
PreparedStatement ps = connection.prepareStatement(query);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
String fName = rs.getString("First_Name");
String lName = rs.getString("Last_Name");
String address = rs.getString("Address");
String phone = rs.getString("Phone_Number");
String accNum = rs.getString("Account_Number");
String balance = rs.getString("Balance");
c.setFirstName(fName);
c.setLastName(lName);
c.setAddress(address);
c.setPhoneNumber(phone);
c.setAccountNumber(accNum);
c.setBalance(balance);
}
return c;
} catch (SQLException e) {
System.err.println(e);
}
return null;
}
}
Here is the method that is linked to the button I use to perform what I'm trying to attempt. It's part of the Controller class. I believe this method is also a part of the problem. Any ideas? Thank for all you guys do. This website is a real benefit to the community.
public void next() {
Customers c = new Customers();
DBInterface.getAccounts(c);
firstNameF2.setText(c.getFirstName());
lastNameF2.setText(c.getLastName());
addressF2.setText(c.getAddress());
phoneNumberF2.setText(c.getPhoneNumber());
accNumF.setText(c.getAccountNumber());
balanceF.setText(c.getBalance());
}
If you are expecting to get multiple Customers objects, then you definitely should return a list of that.
public static List<Customers> getAccounts() {
// Whatever you originally had...
final List<Customers> ret = new ArrayList<>();
while (rs.next()) {
String fName = rs.getString("First_Name");
String lName = rs.getString("Last_Name");
String address = rs.getString("Address");
String phone = rs.getString("Phone_Number");
String accNum = rs.getString("Account_Number");
String balance = rs.getString("Balance");
final Customers cust = new Customers();
cust.setFirstName(fName);
cust.setLastName(lName);
cust.setAddress(address);
cust.setPhoneNumber(phone);
cust.setAccountNumber(accNum);
cust.setBalance(balance);
ret.add(cust);
}
return ret;
}
I have removed the part about passing in the instance of Customers (which would have ended up as passing in List<Customers>. If you really need to do that, you can add back in and do all the necessary checks.

How to get out integer from database using IDataReader and Mapper

I'm very new in programming and this is my first post (question) here, so please don't judge me.
I'm trying to build my first individual WCF service for my project. Let me first display my code , so it will be easier to understand.
This is my data access layer:
public class DataAccessLayer : IDisposable
{
string DBConnectionString = "DBCS";
public int ValidateUser(string employeeLogin, string employeePassword)
{
int outputResult = 0;
try
{
DatabaseProviderFactory factory = new DatabaseProviderFactory();
Database db = factory.Create(DBConnectionString);
string storedProcedureName = "uspValidateUser";
DbCommand dbCommand = db.GetStoredProcCommand(storedProcedureName);
db.AddInParameter(dbCommand, "#EmployeeLogin", DbType.String, employeeLogin);
db.AddInParameter(dbCommand, "#EmployeePassword", DbType.String, employeePassword);
db.AddOutParameter(dbCommand, "#OutRes", DbType.Int32, outputResult);
using (IDataReader reader = db.ExecuteReader(dbCommand))
{
Mapper.Reset();
Mapper.CreateMap<IDataReader, Int32>();
outputResult = (int)Mapper.Map<IDataReader, Int32>(reader);
}
}
catch (Exception ex)
{
throw ex;
}
return outputResult;
}
public void Dispose()
{
}
}
This is my stored procedure:
ALTER PROCEDURE [dbo].[uspValidateUser]
#EmployeeLogin VARCHAR(20),
#EmployeePassword VARCHAR(20),
#OutRes int Output
AS
SET #OutRes = (select count(*)
from dbo.tblEmployee
where EmployeeLogin = #EmployeeLogin
and EmployeePassword = #EmployeePassword)
if (#OutRes = 1)
BEGIN
SET NOCOUNT ON;
set #OutRes = 1 --Login is correct
end
else
BEGIN
set #OutRes = 0 -- Login is incorrect
END
And code behind my web form:
public int ValidateUser(string employeeLogin, string employeePassword)
{
int outputResults = 0;
try
{
using (HospitalWCFService.ContractsClient objWCFService = new HospitalWCFService.ContractsClient())
{
outputResults = objWCFService.ValidateUser(employeeLogin, employeePassword);
}
}
catch (Exception ex)
{
lgnEmployeeLogin.FailureText = ex.Message;
}
return outputResults;
}
protected void ValidateUser(object sender, AuthenticateEventArgs e)
{
int outputResults = 0;
outputResults = ValidateUser(lgnEmployeeLogin.UserName, lgnEmployeeLogin.Password);
if (outputResults == 1)
{
Session["UserName"] = lgnEmployeeLogin.UserName.ToString();
FormsAuthentication.RedirectFromLoginPage(lgnEmployeeLogin.UserName, lgnEmployeeLogin.RememberMeSet);
}
else
{
lgnEmployeeLogin.FailureText = "Username and/or password is incorrect.";
}
}
To get user credentials I'm using login control lgnEmployeeLogin.
I'm having problems of retrieving that output integer #OutRes parameter from database using Mapper (I need to use mapper)
If it is possible, please explain solution in easiest language possible as I might not understand difficult technical slang.
Thank you all in advance!
Your lack of answers could be because you say that you have to use mapper - but I chose to ignore that, because ExecuteReader is for dealing with the rows and columns returned by a stored procedure, not for its output parameters. The stored procedure you provided has no result set!
This could be as simple as
db.ExecuteNonQuery();
OutputResult = db.Parameters( "#OutRes").value
to be clear, this replaces your using...ExecuteReader block
Also note: your code did not deal with opening (and closing) the SQL connection (db.Connection.Open();, so I ignored that here too.

How to scan huge tables in datastore

Here is my problem ..
We have a User table with over 50 million users. Now I want to retrieve some fbIds that I need to test a method (i.e. readUsersByFacebookIds())
My naive first attempt was to scan some records having a facebookId that is not null and then use those fbIds. This question timed out and my colleague mentioned that DataStore could have a hard time with NOT_EQUAL. I.e. can't use the index. (Sounds reasonable ...)
Attempt #1 Times out i.e. > 60 secs
public String testFbFriends(int count) {
try {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Query q = new Query("User");
q.setFilter(new FilterPredicate("facebookId", Query.FilterOperator.NOT_EQUAL, null));
PreparedQuery pq = ds.prepare(q);
List<String> fbIds = new ArrayList<String>();
for (Entity userE : pq.asIterable(FetchOptions.Builder.withLimit(count).chunkSize(100))) {
User u = new User(1, userE, false);
fbIds.add(u.getFacebookId());
if (fbIds.size() >= count)
break;
}
List<User> users = UserModule.getInstance().readUsersByFacebookIds(1, fbIds, 0, 0);
return jsn.toJson(users);
} catch (Exception e) {
return STR.getStackTrace(e);
}
}
My second attempt was to scan a number of users and skip those where facebookId is null.
Attempt #2 - Also times out ...
public String testFbFriends(int count) {
try {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Query q = new Query("User");
// q.setFilter(new FilterPredicate("facebookId", Query.FilterOperator.NOT_EQUAL, null));
PreparedQuery pq = ds.prepare(q);
List<String> fbIds = new ArrayList<String>();
for (Entity userE : pq.asIterable(FetchOptions.Builder.withLimit(count * 4).chunkSize(100))) {
User u = new User(1, userE, false);
if (u.getFacebookId() != null) {
fbIds.add(u.getFacebookId());
if (fbIds.size() >= count)
break;
}
}
List<User> users = UserModule.getInstance().readUsersByFacebookIds(1, fbIds, 0, 0);
return jsn.toJson(users);
} catch (Exception e) {
return STR.getStackTrace(e);
}
}
So does anyone out there know how to scan some records from a HUGE table?
Big thanks in advance!
Have you tried using cursors?
...
Query q = new Query("User");
if (cursorString != null) {
Cursor cursor = Cursor.fromWebSafeString(cursorString);
Map<String, Object> extensionMap = new HashMap<String, Object>();
extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, cursor);
q.setExtensions(extensionMap);
}
q.setRange(0, range);
...retrieve entities...
Cursor cursor = JDOCursorHelper.getCursor(results);
cursorString = cursor.toWebSafeString();
...
With cursors you can set the number of entities retrieved in each call, and avoid timeout.

DatabaseIOException When Executing Query "Delete"

Can anybody help telling me what is wrong with my code? I am trying to connect to SQLite database, and executing some queries. when trying to create and open the database, create and insert the table, no exception returned. but when I try to execute delete statement,
DatabaseIOException: File system error (12)
always returned. I don't know the cause of the exception exactly. would you tell me what usually cause this kind of exception? I don't even know when I need to close the database and when I don't need to. this solution also makes me confused.
here is my code:
public class DatabaseManager {
Logger log = new Logger();
Database db;
public DatabaseManager() {
createDatabase();
}
private void createDatabase() {
// Determine if an SDCard is present
boolean sdCardPresent = false;
String root = null;
Enumeration enum = FileSystemRegistry.listRoots();
while (enum.hasMoreElements()) {
root = (String) enum.nextElement();
if(root.equalsIgnoreCase("sdcard/")) {
sdCardPresent = true;
}
}
if(!sdCardPresent) {
alert("This application requires an SD card to be present. Exiting application...");
}
else {
try {
URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
db = DatabaseFactory.openOrCreate(uri);
db.close();
//alert("Database OK!");
} catch (Exception e) {
// TODO Auto-generated catch block
//alert("Exception in createDatabase(): " + e);
}
}
}
private void alert(final String message) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.inform(message);
System.exit(0);
}
});
}
private void createTableTask() {
try {
URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
db = DatabaseFactory.open(uri);
Statement st = db.createStatement("CREATE TABLE IF NOT EXISTS t_task (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "client TEXT, task TEXT)");
st.prepare();
st.execute();
st.close();
db.close();
//alert("Table Task created!");
} catch (Exception e) {
// TODO: handle exception
//alert("Exception in createTableTask(): " + e);
}
}
private void insertTableTask() {
String[] clients = { "Budi Setiawan", "Dian Kusuma", "Joko Ahmad", "Titi Haryanto", "Wahyu" };
String[] tasks = {
"Penawaran terhadap instalasi server",
"Follow up untuk keperluan produk terbaru",
"Pendekatan untuk membina relasi",
"Penawaran jasa maintenance",
"Penawaran terhadap instalasi database"
};
try {
URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
db = DatabaseFactory.open(uri);
for(int i = 0; i < clients.length; i++) {
Statement st = db.createStatement("INSERT INTO t_task (client, task) VALUES (?, ?)");
st.prepare();
st.bind(1, clients[i]);
st.bind(2, tasks[i]);
st.execute();
st.close();
}
db.close();
} catch (Exception e) {
// TODO: handle exception
//alert("Exception in insertTableTask(): " + e);
}
}
public void loadInitialData() {
createTableTask();
insertTableTask();
}
public Cursor getTasks() {
// TODO Auto-generated method stub
Cursor results = null;
try {
URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
db = DatabaseFactory.open(uri);
Statement st = db.createStatement("SELECT client, task FROM t_task");
st.prepare();
results = st.getCursor();
return results;
} catch (Exception e) {
// TODO: handle exception
//alert("Exception: " + e);
}
return results;
}
public void delete(String string) {
// TODO Auto-generated method stub
try {
URI uri = URI.create("/SDCard/databases/MyAdvanceUI/myadvanceui.db");
db = DatabaseFactory.open(uri);
Statement st = db.createStatement("DELETE FROM t_task WHERE client=?");
st.prepare();
st.bind(1, string);
st.execute();
} catch (Exception e) {
// TODO: handle exception
alert("Exception: " + e);
}
}
}
thank you for your help.
I don't see that you close the statement and close the database after select and delete actions. Most probably you can't open database because it wasn't closed correctly.
Big warning SD card isn't available when user mounted devices to PC as external drive. Some devices are going without SD card preinstalled. DB operations are really slow on 5 OS devices. Your alert method code wan't close db what could be issue to open it after on the next application start.
Warning As #pankar mentioned in comment you should add finally {} where you will close resources for sure. In your current implementation if you get exception in execution you will never close database.
Big improvements You don't need to create and prepare statement every loop. Just do it before for. Do bind and execute every loop. And close statement after for.
Improvements You could keep one opened db during application run cycle. It will save you some line of code and time for opening closing.
Notation It's bad practice to have parameter named like 'string'. I would rename it to something more meaningful.

Resources