diff --git a/tools/pom.xml b/tools/pom.xml
index bb0435d434..3b163b44b3 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -56,8 +56,9 @@
             cassandra-all
         
         
-            com.datastax.oss
-            java-driver-core
+            com.datastax.cassandra
+            cassandra-driver-core
+            3.10.1
         
         
             commons-io
diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java
new file mode 100644
index 0000000000..d88b4361da
--- /dev/null
+++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java
@@ -0,0 +1,55 @@
+package org.thingsboard.client.tools.migrator;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.LineIterator;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class DictionaryParser {
+    private Map dictionaryParsed = new HashMap<>();
+
+    public DictionaryParser(File sourceFile) throws IOException {
+        parseDictionaryDump(FileUtils.lineIterator(sourceFile));
+    }
+
+    public String getKeyByKeyId(String keyId) {
+        return dictionaryParsed.get(keyId);
+    }
+
+    private boolean isBlockFinished(String line) {
+        return StringUtils.isBlank(line) || line.equals("\\.");
+    }
+
+    private boolean isBlockStarted(String line) {
+        return line.startsWith("COPY public.ts_kv_dictionary (");
+    }
+
+    private void parseDictionaryDump(LineIterator iterator) {
+        String tempLine;
+        while(iterator.hasNext()) {
+            tempLine = iterator.nextLine();
+
+            if(isBlockStarted(tempLine)) {
+                processBlock(iterator);
+            }
+        }
+    }
+
+    private void processBlock(LineIterator lineIterator) {
+        String tempLine;
+        String[] lineSplited;
+        while(lineIterator.hasNext()) {
+            tempLine = lineIterator.nextLine();
+            if(isBlockFinished(tempLine)) {
+                return;
+            }
+
+            lineSplited = tempLine.split("\t");
+            dictionaryParsed.put(lineSplited[1], lineSplited[0]);
+        }
+    }
+}
diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/MigratorTool.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/MigratorTool.java
index e3a98e974f..83ca54624a 100644
--- a/tools/src/main/java/org/thingsboard/client/tools/migrator/MigratorTool.java
+++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/MigratorTool.java
@@ -30,17 +30,25 @@ public class MigratorTool {
     public static void main(String[] args) {
         CommandLine cmd = parseArgs(args);
 
-
         try {
-            File latestSource = new File(cmd.getOptionValue("latestTelemetryFrom"));
-            File latestSaveDir = new File(cmd.getOptionValue("latestTelemetryOut"));
-            File tsSource = new File(cmd.getOptionValue("telemetryFrom"));
-            File tsSaveDir = new File(cmd.getOptionValue("telemetryOut"));
-            File partitionsSaveDir = new File(cmd.getOptionValue("partitionsOut"));
             boolean castEnable = Boolean.parseBoolean(cmd.getOptionValue("castEnable"));
+            File allTelemetrySource = new File(cmd.getOptionValue("telemetryFrom"));
 
-            PgCaLatestMigrator.migrateLatest(latestSource, latestSaveDir, castEnable);
-            PostgresToCassandraTelemetryMigrator.migrateTs(tsSource, tsSaveDir, partitionsSaveDir, castEnable);
+            RelatedEntitiesParser allEntityIdsAndTypes =
+                    new RelatedEntitiesParser(new File(cmd.getOptionValue("relatedEntities")));
+            DictionaryParser dictionaryParser = new DictionaryParser(allTelemetrySource);
+
+            if(cmd.getOptionValue("latestTelemetryOut") != null) {
+                File latestSaveDir = new File(cmd.getOptionValue("latestTelemetryOut"));
+                PgCaLatestMigrator.migrateLatest(allTelemetrySource, latestSaveDir, allEntityIdsAndTypes, dictionaryParser, castEnable);
+            }
+            if(cmd.getOptionValue("telemetryOut") != null) {
+                File tsSaveDir = new File(cmd.getOptionValue("telemetryOut"));
+                File partitionsSaveDir = new File(cmd.getOptionValue("partitionsOut"));
+                PostgresToCassandraTelemetryMigrator.migrateTs(
+                        allTelemetrySource, tsSaveDir, partitionsSaveDir, allEntityIdsAndTypes, dictionaryParser, castEnable
+                );
+            }
 
         } catch (Throwable th) {
             th.printStackTrace();
@@ -52,30 +60,30 @@ public class MigratorTool {
     private static CommandLine parseArgs(String[] args) {
         Options options = new Options();
 
-        Option latestTsOpt = new Option("latestFrom", "latestTelemetryFrom", true, "latest telemetry source file path");
-        latestTsOpt.setRequired(true);
-        options.addOption(latestTsOpt);
+        Option telemetryAllFrom = new Option("telemetryFrom", "telemetryFrom", true, "telemetry source file");
+        telemetryAllFrom.setRequired(true);
+        options.addOption(telemetryAllFrom);
 
         Option latestTsOutOpt = new Option("latestOut", "latestTelemetryOut", true, "latest telemetry save dir");
-        latestTsOutOpt.setRequired(true);
+        latestTsOutOpt.setRequired(false);
         options.addOption(latestTsOutOpt);
 
-        Option tsOpt = new Option("tsFrom", "telemetryFrom", true, "telemetry source file path");
-        tsOpt.setRequired(true);
-        options.addOption(tsOpt);
-
         Option tsOutOpt = new Option("tsOut", "telemetryOut", true, "sstable save dir");
-        tsOutOpt.setRequired(true);
+        tsOutOpt.setRequired(false);
         options.addOption(tsOutOpt);
 
         Option partitionOutOpt = new Option("partitionsOut", "partitionsOut", true, "partitions save dir");
-        partitionOutOpt.setRequired(true);
+        partitionOutOpt.setRequired(false);
         options.addOption(partitionOutOpt);
 
         Option castOpt = new Option("castEnable", "castEnable", true, "cast String to Double if possible");
         castOpt.setRequired(true);
         options.addOption(castOpt);
 
+        Option relatedOpt = new Option("relatedEntities", "relatedEntities", true, "related entities source file path");
+        relatedOpt.setRequired(true);
+        options.addOption(relatedOpt);
+
         HelpFormatter formatter = new HelpFormatter();
         CommandLineParser parser = new BasicParser();
 
diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaLatestMigrator.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaLatestMigrator.java
index 5f0a84c7f4..5d4a2a6e81 100644
--- a/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaLatestMigrator.java
+++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/PgCaLatestMigrator.java
@@ -43,14 +43,21 @@ public class PgCaLatestMigrator {
     private static long castedOk = 0;
 
     private static long currentWriterCount = 1;
-    private static CQLSSTableWriter currentTsWriter = null;
+    private static RelatedEntitiesParser allIdsAndTypes;
+    private static DictionaryParser keyPairs;
 
-    public static void migrateLatest(File sourceFile, File outDir, boolean castStringsIfPossible) throws IOException {
+    public static void migrateLatest(File sourceFile,
+                                     File outDir,
+                                     RelatedEntitiesParser allEntityIdsAndTypes,
+                                     DictionaryParser dictionaryParser,
+                                     boolean castStringsIfPossible) throws IOException {
         long startTs = System.currentTimeMillis();
         long stepLineTs = System.currentTimeMillis();
         long stepOkLineTs = System.currentTimeMillis();
         LineIterator iterator = FileUtils.lineIterator(sourceFile);
-        currentTsWriter = WriterBuilder.getTsWriter(outDir);
+        CQLSSTableWriter currentTsWriter = WriterBuilder.getLatestWriter(outDir);
+        allIdsAndTypes = allEntityIdsAndTypes;
+        keyPairs = dictionaryParser;
 
         boolean isBlockStarted = false;
         boolean isBlockFinished = false;
@@ -107,7 +114,7 @@ public class PgCaLatestMigrator {
                     }
 
                     if (linesMigrated++ % LOG_BATCH == 0) {
-                        System.out.println(new Date() + " migrated = " + linesMigrated + " in " + (System.currentTimeMillis() - stepOkLineTs));
+                        System.out.println(new Date() + " migrated = " + linesMigrated + " in " + (System.currentTimeMillis() - stepOkLineTs) + " ms.");
                         stepOkLineTs = System.currentTimeMillis();
                     }
                 } catch (Exception ex) {
@@ -119,7 +126,7 @@ public class PgCaLatestMigrator {
 
         long endTs = System.currentTimeMillis();
         System.out.println();
-        System.out.println(new Date() + " Migrated rows " + linesMigrated + " in " + (endTs - startTs));
+        System.out.println(new Date() + " Migrated rows " + linesMigrated + " in " + (endTs - startTs) + " ts");
 
         currentTsWriter.close();
         System.out.println();
@@ -146,34 +153,31 @@ public class PgCaLatestMigrator {
 
     private static List