[PYTHON] Ich habe versucht, mit PartiQL und MongoDB verbunden zu spielen

Voraussetzungen

Dieser Artikel beschreibt, was wir über PartiQL recherchiert haben. Ich denke, dass es Mängel wie Auslassungen im Inhalt gibt. In diesem Fall würde ich es begrüßen, wenn Sie in der Bearbeitungsanforderung oder im Kommentar darauf hinweisen könnten. Dieser Artikel wurde am 7. November 2019 verfasst. PartiQL wurde gerade angekündigt, und ich denke, dass es im Verlauf der Implementierung möglicherweise ungeeignet wird. Verzeihen Sie diesen Punkt.

Was ist PartiQL?

PartiQL ist eine SQL-kompatible Sprache, die von Amazon als OpenSource veröffentlicht wird. Als Feature kann eine Vielzahl von DB-Formularen gesteuert werden, und es scheint, dass es neben RDB auch verschachtelte Daten wie JSON verarbeiten kann.

Informationen zum tatsächlichen Betrieb finden Sie in Tutorial. Wenn Sie SQL gut kennen, können Sie es intuitiv bedienen. Zu diesem Zeitpunkt scheint die Anweisung Update / delete / Insert nicht implementiert zu sein.

Ich habe versucht, mich mit MongoDB zu verbinden.

Hier ist das Hauptproblem. Dieses PartiQL verwendet PartQL, anstatt eine eigene Sprache als Abfragesprache für die API hinzuzufügen, wenn Suchfunktionen und statistische Verarbeitungsfunktionen zum Dienst hinzugefügt werden ([SPL] in Splunk (https://docs.splunk.com). /Documentation/Splunk/8.0.0/SearchReference/UnderstandingSPLsyntax)) Es scheint einen Anwendungsfall zu geben. Obwohl es noch in der Alpha-Version ist, habe ich es mit MongoDB verbunden und es tatsächlich ausprobiert.

Installieren Sie zunächst PartiQL. Wenn Sie auf der offiziellen Website unter Erste Schritte nachsehen, können Sie es problemlos installieren. Darüber hinaus ist JRE als Voraussetzung erforderlich. Es wurde bestätigt, dass dies mit OpenJRE9 funktioniert.

Sie können PartiQL im REPL-Format ausprobieren, indem Sie Befehle ausführen und Benutzereingaben interaktiv ausführen.

$ ./bin/partiql
Welcome to the PartiQL REPL!
PartiQL> 

Es scheint jedoch, dass zu diesem Zeitpunkt keine weitere Implementierung durchgeführt wurde und es keinen bestimmten Konnektor mit MongoDB gibt.

Daher werden wir in diesem Artikel Python verwenden, um einen PoC zu erstellen, der das Ergebnis der Ausführung von partiql aus dem Subprozessmodul ausgibt, wobei die PartiQL-Eingabeabfrage des Benutzers und die von der DB im Pymongo-Modul erfassten Daten als Argumente verwendet werden.

Für diejenigen, die nur die Ergebnisse unten wissen wollen

Das Folgende ist der eigentliche PoC-Prototyp. Es nimmt Informationen aus MongoDB und zeigt das Ergebnis der PariQL-Abfragesuche an. (Es wird keine Fehlerbehandlung durchgeführt.)

partiQLCtl.py


import subprocess
import json
import os
import pymongo

class PartiQLCtl():
    def __init__(self, address=None, port=None):
        # address,Wenn keine Beschreibung des Ports vorhanden ist, suchen Sie durch direkte Eingabe der Suchquellendaten JSON
        if (address is not None) and (port is not None):
            self.client = pymongo.MongoClient(address, port)
        else:
            self.client = None

    def load_json_data(self, json_data):
        #Quelldaten suchen JSON-Funktion zur direkten Eingabe
        self.env_data = self.convert_json_to_partiql(json_data)
        print(self.env_data)

    def load_db_data(self, db, collection):
        #Extrahieren Sie Suchquelldaten aus MongoDB
        cur = self.client[db][collection].find({})

        #Das DB-Ausgabeergebnis sind Daten['record']Speichern Sie als Liste unten
        data = {"record": []}
        for record in cur:
            # _String-Verarbeitung von id
            record['_id'] = str(record['_id'])
            data["record"].append(record)

        self.env_data = self.convert_json_to_partiql(data)
        
    def execute(self, query):
        #Funktion zum Ausführen einer Abfrage

        # -Dummy-Daten für i-Optionen. Es ist notwendig, im Voraus eine Datei zu erstellen. Der Inhalt ist"{}"Nur die aus zwei Buchstaben bestehende Beschreibung von
        ion_file_path = os.path.join(os.path.dirname(__file__), '../tmp/tmp.ion')
        # -Durchsuchen Sie die Quelldaten nach der Option e. Erstellen Sie eine Datei in diesem Skript. Ändern Sie den Standort nach Bedarf
        env_file_path = os.path.join(os.path.dirname(__file__), '../tmp/env.ion')
        #Ausführungsdatei. Ändern Sie den Standort nach Bedarf
        partiql_execute_path = os.path.join(os.path.dirname(__file__),'../dist/partiql/bin/partiql')

        with open(env_file_path, 'w') as f:
            f.write(self.env_data)

        res = subprocess.check_output([partiql_execute_path, '-q', query, '-i', ion_file_path, '-e', env_file_path])
        return res
    
    def convert_json_to_partiql(self, json):
        #Eine Funktion, die JSON in das Datenformat für PartiQL ändert. aufführen/dict/boolean/int/Unterstützt den str-Typ
        if type(json) is list:
            env = "<<"
            for idx, elem in enumerate(json):
                if (type(elem) is dict) or (type(elem) is list):
                    env += (self.convert_json_to_partiql(elem))
                elif type(elem) == str:
                    env += "'{}'".format(elem)
                elif elem is None:
                    env += "null"
                elif elem is True:
                    env += "true"
                elif elem is False:
                    env += "false"
                else:
                    env += str(elem)

                if idx != len(json) - 1:
                    env += ', '
                
            env += '>>'
        elif type(json) is dict:
            env = '{'
            for idx, elem in enumerate(json.keys()):
                if (type(json[elem]) is dict) or (type(json[elem]) is list):
                    env += "'{}': {}".format(elem, self.convert_json_to_partiql(json[elem]))
                elif type(json[elem]) == str:
                    env += "'{}': '{}'".format(elem, json[elem])
                elif json[elem] is None:
                    env += "'{}': null".format(elem)
                elif json[elem] is True:
                    env += "'{}': true".format(elem)
                elif json[elem] is False:
                    env += "'{}': false".format(elem)
                else:
                    env += "'{}': {}".format(elem, str(json[elem]))
                
                if idx != len(json.keys()) - 1:
                    env += ', '
            env += '}'

        return env


if __name__ == '__main__':
    pql = PartiQLCtl("192.168.1.10", 27017)
    pql.load_db_data("test", "test")
    print(pql.execute("select r.id from record r"))

Darüber hinaus werden die folgenden Daten vorab in MongoDB gespeichert.

> use test
switched to db test
> db.test.insert({"id": "aa", "setting": [{"config1": "hoge", "config2": "fuga"}]})
WriteResult({ "nInserted" : 1 })
> db.test.insert({"id": "bb", "setting": [{"config1": "hoge2", "config2": "fuga2"}]})

Das Ausführungsergebnis ist wie folgt.

$ python partiQlCtl.py 
b"<<\n  {\n    'id': 'aa'\n  },\n  {\n    'id': 'bb'\n  }\n>>"

Versuchen Sie festzustellen, dass die Anzeigedaten geändert werden, indem Sie das letzte Argument pql.execute (PartiQl-Abfrage) ändern.

Der folgende Versuch und Irrtum bis zur PoC-Erstellung

Wenn Sie die Hilfe von partiql ausführen, können Sie sie anscheinend auch als anderen Befehl als REPL ausführen, wie unten gezeigt.

$ ./bin/partiql -h
PartiQL CLI
Command line interface for executing PartiQL queries. Can be run in an interactive (REPL) mode or non-interactive.

Examples:
To run in REPL mode simply execute the executable without any arguments:
     partiql

In non-interactive mode we use Ion as the format for input data which is bound to a global variable 
named "input_data", in the example below /logs/log.ion is bound to "input_data":
     partiql --query="SELECT * FROM input_data" --input=/logs/log.ion

The cli can output using PartiQL syntax or Ion using the --output-format option, e.g. to output binary ion:
     partiql --query="SELECT * FROM input_data" --output-format=ION_BINARY --input=/logs/log.ion

To pipe input data in via stdin:
     cat /logs/log.ion | sqlcli --query="SELECT * FROM input_data" --format=ION_BINARY > output.10n

Option                                Description                                                
------                                -----------                                                
-e, --environment <File>              initial global environment (optional)                      
-h, --help                            prints this help                                           
-i, --input <File>                    input file, requires the query option (default: stdin)     
-o, --output <File>                   output file, requires the query option (default: stdout)   
--of, --output-format <OutputFormat:  output format, requires the query option (default: PARTIQL)
  (ION_TEXT|ION_BINARY|PARTIQL)>                                                                 
-q, --query <String>                  PartiQL query, triggers non interactive mode 

Es scheint, dass Sie eine Abfragesuche für die Shell durchführen können, indem Sie den folgenden Befehl ausführen.

partiql --query="SELECT * FROM input_data" --input=/logs/log.ion

Hier gibt es eine Aussage, dass --input nur das ION-Format verwenden kann. Für diejenigen, die es hier nicht wissen, ist ION-Format ein von Amazon erstelltes Datenserialisierungsformat und eine JSON-ähnliche Beschreibung des Textformats. Außerdem ist es im Binärformat geschrieben. Modul in Python wird ebenfalls bereitgestellt, sodass Sie JSON ⇔ ION mithilfe dieser Option konvertieren können.

>>> import amazon.ion.simpleion as ion
>>> 
>>> obj = ion.loads('{"id" : "aa", "setting" : [ { "config1" : "hoge", "config2" : "fuga" } ] }')
'$ion_1_0 {id:"aa",setting:[{config1:"hoge",config2:"fuga"}]}'

Wenn Sie das Ausgabeergebnis tatsächlich als test.ion speichern und ausführen, sieht es wie folgt aus.

$ cat test.ion 
$ion_1_0 {id:"aa",setting:[{config1:"hoge",config2:"fuga"}]}
$ ./bin/partiql -q "select * from input_data" -i test.ion 
<<
  {
    'id': 'aa',
    'setting': [
      {
        'config1': 'hoge',
        'config2': 'fuga'
      }
    ]
  }
>>

Als ich hier jedoch einige Dinge ausprobierte und verschachtelte Daten in die from-Klausel eingab, trat ein unerwartetes Ereignis auf, bei dem das Ausgabeergebnis leer war. Hier habe ich es aufgegeben, diese Methode zu verfolgen.

$ ./bin/partiql -q "select * from input_data.setng" -i test.ion  
<<
  {}
>>

Der Austausch des Ausgabeergebnisses von REPL durch Verbinden von PIPE mit Subprocess Popen von Python ist jedoch als Code nicht sehr sauber, daher werden wir eine andere Methode in Betracht ziehen.

Es gibt eine Methode, um die Informationen der Suchquelle der Eingabe hier mit der Option -e zusätzlich zur Option -i einzugeben. (In diesem Fall handelt es sich bei den einzugebenden Daten um PartiQL-Originalformatdaten. Daher ist eine Konvertierung in das JSON⇔PariQL-Originalformat erforderlich.) Mit der Option -q und der Option -e werden Eingabeinformationen jedoch von der Standardeingabe abgehört, sodass sie sich bei Ausführung im Wartezustand der Benutzereingabe befinden. Schließlich habe ich den ursprünglichen Zweck erreicht, indem ich die Option -i Dummy-Daten als Dummy lesen ließ.

Recommended Posts

Ich habe versucht, mit PartiQL und MongoDB verbunden zu spielen
Ich habe versucht, mit Pillow mit dem Bild zu spielen
Ich habe Jacobian und teilweise Differenzierung mit Python versucht
Ich habe Funktionssynthese und Curry mit Python versucht
Ich habe versucht, mit tkinter mit dem Taschenrechner zu spielen
[Einführung in AWS] Ich habe versucht, eine Konversations-App zu portieren und mit text2speech @ AWS playing zu spielen
Ich habe versucht, mit VOICEROID2 2 automatisch zu lesen und zu speichern
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
Ich habe versucht, mit VOICEROID2 automatisch zu lesen und zu speichern
Ich habe versucht, Grad-CAM mit Keras und Tensorflow zu implementieren
[Einführung in AWS] Ich habe versucht, mit der Sprach-Text-Konvertierung zu spielen ♪
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, mit PyCaret zu clustern
Ich habe gRPC mit Python ausprobiert
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, Überlebende der Titanic mit Kaggle vorherzusagen und einzureichen
Ich habe versucht, Raspeye und conect + mit der Web-API zu verbinden
[Einführung in das Modell der Infektionskrankheiten] Ich habe versucht, zu passen und zu spielen ♬
Ich habe versucht, die Benutzeroberfläche neben Python und Tkinter dreiäugig zu gestalten
Ich habe den Chat von YouTube Live angezeigt und versucht zu spielen
Ich habe maschinelles Lernen mit liblinear versucht
Ich habe versucht, WebScraping mit Python.
Ich habe versucht, Essen mit SinGAN zu bewegen
Ich habe versucht, DeepPose mit PyTorch zu implementieren
Ich habe versucht, das Gesicht mit MTCNN zu erkennen
Ich habe mit PyQt5 und Python3 gespielt
Ich habe versucht, Prolog mit Python 3.8.2 auszuführen.
Ich habe die SMTP-Kommunikation mit Python versucht
Ich habe versucht, Sätze mit GPT-2 zu generieren
Ich habe versucht, LightGBM mit Yellowbrick zu lernen
Ich habe versucht, das Gesicht mit OpenCV zu erkennen
Ich habe versucht, die Lesezeichen zu visualisieren, die mit Doc2Vec und PCA nach Slack fliegen
[Systemhandel] Ich habe versucht, mit dem zerlegten stochastischen Oszillator mit Python ♬ zu spielen
Ich habe versucht, natürliche Zahlenausdrücke und arithmetische Verarbeitung nur mit Listenverarbeitung
Ich habe versucht, mit Selenium und Python einen regelmäßigen Ausführungsprozess durchzuführen
Ich habe versucht, PyEZ und JSNAPy zu verwenden. Teil 4: Automatisieren Sie die ISP-Einrichtung mit PyEZ und JSNAPy
Ich habe versucht, Bulls and Cows mit einem Shell-Programm zu erstellen
Ich habe versucht, Gesichtsmarkierungen mit Python und Dlib leicht zu erkennen
Ich habe eine multiple Regressionsanalyse mit Polypoly-Regression versucht
Ich habe versucht, eine SMS mit Twilio zu senden
Ich habe versucht, Amazon SQS mit Django-Sellerie zu verwenden
Ich habe versucht, Autoencoder mit TensorFlow zu implementieren
Ich habe Linebot mit Flasche (Anaconda) + Heroku ausprobiert
Ich habe versucht, AutoEncoder mit TensorFlow zu visualisieren
Ich habe DSX Desktop installiert und ausprobiert
Ich habe versucht, mit Hy anzufangen
Ich versuchte, Trauer und Freude über das Problem der stabilen Ehe auszudrücken.
Ich habe versucht, ○ ✕ mit TensorFlow zu spielen
Ich habe versucht, Selen mit Headless-Chrom zu verwenden
Ich habe versucht, Faktoren mit Titanic-Daten zu analysieren!
Ich habe versucht, mit Kaggles Titanic (kaggle②) zu lernen.
Ich habe versucht, mit Python + opencv nicht realistisch zu rendern
Ich habe versucht, datetime <-> string mit tzinfo mit strftime () und strptime () zu konvertieren.
Ich habe versucht, Linux (CentOS 7) mit dem Überwachungsserver Zabbix lebend zu überwachen (Ping)
Ich habe eine funktionale Sprache mit Python ausprobiert
Ich habe versucht, den Winkel von Sin und Cos mit Chainer zu lernen