Benutzer-Werkzeuge

Webseiten-Werkzeuge


nosql:avro_schema_definieren

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
nosql:avro_schema_definieren [2013/08/17 17:29] – [Schema Definition mit Avro in der Oracle NoSQL Datenbank] gpipperrnosql:avro_schema_definieren [2013/08/17 17:35] (aktuell) gpipperr
Zeile 1: Zeile 1:
 +=====Schema Definition mit Avro in der Oracle NoSQL Datenbank=====
 +
 +===Vorbereitung:===
 +
 +Java Libraries :
 +
 +  * Avro Java Libraries laden von http://www.apache.org/dyn/closer.cgi/avro/ 
 +    * avro-1.7.4.jar
 +    * avro-tools-1.7.4.ja
 +  * Jackson JSON library laden: http://wiki.fasterxml.com/JacksonDownload
 +    * jackson-annotations-2.2.0.jar
 +    * jackson-core-2.2.0.jar
 +    * jackson-databind-2.2.0.jar
 +
 +Libraries in eine Verzeichnis kopieren, in unsere Beispiel unter D:\entwicklung\avro-1.7.4
 +
 +
 +=== Ein Avro Schema definieren ===
 +
 +Datei emp.avsc mit der Schema Definition anlegen:
 +
 +<code emp.avsc>
 +{"namespace": "gpi.avro",
 + "type": "record",
 + "name": "emp",
 + "fields": [
 +     {"name": "EMPNO"   , "type": "int"        , "default" : 0},
 + {"name": "ENAME"   , "type": "string" , "default" : ""},
 + {"name": "JOB"     , "type": "string" , "default" : ""},
 + {"name": "MGR"     , "type": "int"    , "default" : 0},
 + {"name": "HIREDATE", "type": "long"   , "default" : 0},
 + {"name": "SAL"     , "type": "float"  , "default" : 0},
 + {"name": "COMM"    , "type": "float"  , "default" : 0},
 +     {"name": "DEPTNO"  , "type": "int"        , "default" : 10}
 + ]
 +}
 +}
 +</code>
 +
 +Schema Definition siehe hier: [[http://avro.apache.org/docs/current/spec.html#schema_primitive|schema_primitive]] und [[http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuide/avroschemas.html|Avro - Oracle NoSQL Getting Started]]
 +
 +Das erste Problem, dass ins Auge fällt, ist die fehlende native Unterstützung für den Datentyp "date".
 +
 +Wie in der Java Welt üblich, ist hier wie immer etwas Basteln angesagt, oder eben das Speichern des Datumswerts als Long Value.
 +
 +Damit das Schema in der Datenbank später auch angepasst/geändert werden kann, muss ein Default Wert für die einzelnen Spalten definiert werden.
 +
 +=== Schema prüfen und übersetzen ===
 +
 +Mit den Avro Tool kann die Schema Definition überprüft und übersetzt werden.
 +
 +<code powershell>
 +java -jar D:\entwicklung\avro-1.7.4\avro-tools-1.7.4.jar compile schema .\emp.avsc .
 +</code>
 +
 +Damit stehen die passende Java Klassen für die Schema Definition für die Serialisierung zur Verfügung.
 +
 +=== Schema in der NoSQL Datenbank anlegen ===
 +
 +Über die Admin Konsole wird das Schema in der Datenbank angelegt:
 +
 +<code powershell>
 +REM Admin Console starten:
 +java -jar D:\entwicklung\kv-2.1.8\lib\kvstore.jar runadmin -port 5000 -host localhost
 +
 +REM Schema in der DB anlegen:
 +
 +kv-> ddl add-schema -file emp.avsc
 +Added schema: gpi.avro.emp.1
 +
 +REM Schemas in der DB anzeigen lassen:
 +
 +kv-> show schemas
 +gpi.avro.emp
 +  ID: 1  Modified: 2013-08-17 14:14:41 UTC, From: jupiter
 +  
 +</code>
 +
 +=== Wie kann das Avro Schema in meiner Applikation genützt werden? ===
 +
 +Ein Avro Schema  kann auf verschiedene Weise in die eigene Applikation eingebunden werden.
 +
 +
 +  * Generic
 +  * Specific 
 +  * JSON 
 +  * Raw 
 +
 +Für die Details siehe [[http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuide/avrobindings.html | NoSQL Guide Chapter 8]]
 +
 +
 +=== Ein erster Versuch mit einem Generic Binding ===
 +
 +Ein einfaches Beispiel um mit Hilfe der Avro Schema Definition generisch in die DB zu schreiben:
 +
 +(siehe auch [[http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuide/genericbinding-overview.html|NoSQL Guide Generic Binding]])
 +
 +<code java>
 +package com.gpi.oranosql;
 +
 +import java.io.File;
 +import java.io.IOException;
 +
 +import java.util.Date;
 +
 +import oracle.kv.Consistency;
 +import oracle.kv.KVStore;
 +import oracle.kv.KVStoreConfig;
 +import oracle.kv.KVStoreFactory;
 +import oracle.kv.Key;
 +
 +import org.apache.avro.generic.GenericData;
 +import org.apache.avro.generic.GenericRecord;
 +import org.apache.avro.Schema;
 +
 +import oracle.kv.avro.AvroCatalog;
 +import oracle.kv.avro.GenericAvroBinding;
 +
 +public class AvroReadWrite {
 +
 +    // KV Store
 +    public static KVStore kvstore = null;
 +
 +    public AvroReadWrite() {
 +    }
 +
 +    public static void main(String[] args) {
 +
 +        AvroReadWrite avroReadWrite = new AvroReadWrite();
 +
 +        // get the host to connect as first parameter
 +        String host = args[0];
 +        // get the store Name
 +        String store = args[1];
 +
 +        KVStoreConfig kvconfig = new KVStoreConfig(store, host);
 +        // Connect to the store
 +        kvstore = KVStoreFactory.getStore(kvconfig);
 +
 +
 +        // Read the Avro Schema
 +        Schema.Parser parser = null;
 +        try {
 +            parser = new Schema.Parser();
 +            // read our avro schema definition
 +            parser.parse(new File("emp.avsc"));
 +        }
 +        catch (IOException ex) {
 +            System.out.println("Error -- File emp.avsc not found");
 +        }
 +
 +        // parse the schema definition
 +        // !!! Name of the Schema is :: namespace + name !!!
 +        final Schema empSchema = parser.getTypes().get("gpi.avro.emp");
 +
 +        // connect to store and read Avro schema defintion in the database
 +        AvroCatalog catalog = kvstore.getAvroCatalog();
 +        //debug
 +        //System.out.println("Info --" + catalog.getCurrentSchemas());
 +        
 +        // Generic Binding
 +        GenericAvroBinding binding = catalog.getGenericBinding(empSchema);
 +
 +        // Define the  emp record
 +        GenericRecord emp = new GenericData.Record(empSchema);
 +        
 +        // put values in the record:
 +        emp.put("EMPNO", 7898);
 +        emp.put("ENAME", "SCOTT");
 +        emp.put("JOB", "CLERK");
 +        emp.put("MGR", 1000);
 +        emp.put("HIREDATE", new Date().getTime());
 +        emp.put("SAL", 12000f);
 +        emp.put("COMM", 30f);
 +        emp.put("DEPTNO", 10);
 +
 +        // Create the Key wiht minor und mayor component
 +        Key key = Key.createKey("Mayer", "7899");
 +
 +        // put the emp record into the store
 +        kvstore.put(key, binding.toValue(emp));
 +
 +        //close the store
 +        kvstore.close();
 +
 +        System.exit(0);
 +
 +    }
 +}
 +
 +</code>
 +
 +Mit dem Client Tool kvcli testen:
 +
 +<code powershell>
 +java -jar D:\entwicklung\kv-2.1.8\lib\kvcli.jar -host localhost -port 5000 -store kvstore
 +kvshell-> get -all
 +/SCOTT/-/7898
 +{
 +  "EMPNO" : 7898,
 +  "ENAME" : "SCOTT",
 +  "JOB" : "CLERK",
 +  "MGR" : 1000,
 +  "HIREDATE" : 1376751935296,
 +  "SAL" : 12000.0,
 +  "COMM" : 30.0,
 +  "DEPTNO" : 10
 +}
 +</code>
 +
 +
 +Werte im Programm auslesen:
 +<code java>
 +
 + // see code above for the connection to the database
 +
 + GenericRecord emp2;
 + Key key2 = Key.createKey("Mayer", "7899");
 + ValueVersion vv = kvstore.get(key2);
 +
 + if (vv != null) {
 +          
 +    emp2 = binding.toObject(vv.getValue());
 +        
 +    String empno = emp2.get("EMPNO").toString();
 +    String ename = emp2.get("ENAME").toString();
 +    String job   = emp2.get("JOB").toString();
 +            
 +    int mgr = (Integer)emp2.get("MGR");
 +            
 +    long time = (Long)emp2.get("HIREDATE");
 +    Date hiredate = new Date();
 +    hiredate.setTime(time);
 +
 +    System.out.println(" EMPNO    ::"+empno);
 +    System.out.println(" ENAME    ::"+ename);
 +    System.out.println(" JOB      ::"+job);
 +    System.out.println(" MGR      ::"+mgr);
 +    System.out.println(" HIREDATE ::"+hiredate);
 + }
 +
 +
 +</code>
 +
 +
 +
 +
 +
 +==== Quellen ====
 +
 +Dokumentation:
 +
 +  * http://avro.apache.org/docs/current/gettingstartedjava.html
 +
 +
 +Allgemein:
 +  * http://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
  
nosql/avro_schema_definieren.txt · Zuletzt geändert: 2013/08/17 17:35 von gpipperr