[PYTHON] J'ai essayé de jouer en connectant PartiQL et MongoDB

Conditions préalables

Cet article décrit ce que nous avons recherché sur PartiQL. Je pense qu'il y a des lacunes telles que des omissions dans le contenu, donc dans ce cas, j'apprécierais que vous puissiez le signaler dans la demande de modification ou dans un commentaire. Cet article a été rédigé le 7 novembre 2019. PartiQL vient d'être annoncé, et je pense que cela peut devenir inadapté à mesure que la mise en œuvre progresse régulièrement, alors pardonnez ce point.

Qu'est-ce que PartiQL

PartiQL est un langage compatible SQL publié par Amazon sous le nom d'OpenSource. En tant que fonctionnalité, il peut avoir un large éventail de formes de base de données à contrôler, et il semble qu'il puisse gérer des données imbriquées telles que JSON en plus de RDB.

Pour le fonctionnement réel, veuillez vous référer au Tutoriel. Si vous connaissez assez bien SQL, vous pouvez l'utiliser de manière intuitive. À ce stade, l'instruction Update / delete / Insert ne semble pas être implémentée.

J'ai essayé de me connecter avec MongoDB.

Voici le problème principal. Ce PartiQL utilise PartQL au lieu d'ajouter son propre langage comme langage de requête pour l'API lors de l'ajout d'une fonction de recherche et d'une fonction de traitement statistique au service ([SPL] dans Splunk (https://docs.splunk.com) /Documentation/Splunk/8.0.0/SearchReference/UnderstandingSPLsyntax)) Il semble y avoir un cas d'utilisation. Donc, bien qu'il soit toujours en version alpha, je l'ai connecté à MongoDB et l'ai essayé.

Tout d'abord, installez PartiQL.Si vous regardez Getting Start sur le site officiel, vous pouvez l'installer sans aucun problème. De plus, JRE est requis comme condition préalable. Cela a été confirmé pour fonctionner avec OpenJRE9.

Vous pouvez essayer PartiQL au format REPL en exécutant la commande et en exécutant de manière interactive l'entrée de l'utilisateur.

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

Cependant, il semble qu'aucune autre implémentation n'ait été faite à ce stade, et il n'y a pas de connecteur particulier avec MongoDB.

Par conséquent, dans cet article, nous utiliserons Python pour créer un PoC qui génère le résultat de l'exécution de partiql depuis le module Subprocess, en utilisant la requête d'entrée PartiQL de l'utilisateur et les données acquises de la base de données dans le module Pymongo comme arguments.

Pour ceux qui ne veulent connaître que les résultats ci-dessous

Ce qui suit est le prototype réel du PoC. Il prend des informations de MongoDB et affiche le résultat de la recherche de requête PariQL. (Aucune gestion des erreurs n'est effectuée)

partiQLCtl.py


import subprocess
import json
import os
import pymongo

class PartiQLCtl():
    def __init__(self, address=None, port=None):
        # address,S'il n'y a pas de description du port, recherchez par saisie directe des données de source de recherche 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):
        #Fonction JSON de recherche de données source pour une entrée directe
        self.env_data = self.convert_json_to_partiql(json_data)
        print(self.env_data)

    def load_db_data(self, db, collection):
        #Extraire les données de la source de recherche de MongoDB
        cur = self.client[db][collection].find({})

        #Le résultat de la sortie DB est des données['record']Enregistrer sous la liste ci-dessous
        data = {"record": []}
        for record in cur:
            # _Traitement de chaîne de l'identifiant
            record['_id'] = str(record['_id'])
            data["record"].append(record)

        self.env_data = self.convert_json_to_partiql(data)
        
    def execute(self, query):
        #Fonction d'exécution d'une requête

        # -Données factices pour les options i. Il est nécessaire de créer un fichier au préalable. Le contenu est"{}"Seule la description en deux lettres de
        ion_file_path = os.path.join(os.path.dirname(__file__), '../tmp/tmp.ion')
        # -Recherchez dans les données source l'option e. Créez un fichier dans ce script. Changez d'emplacement au besoin
        env_file_path = os.path.join(os.path.dirname(__file__), '../tmp/env.ion')
        #Fichier d'exécution. Changez d'emplacement au besoin
        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):
        #Une fonction qui change JSON en format de données pour PartiQL. liste/dict/boolean/int/Prend en charge le type str
        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"))

De plus, les données suivantes sont stockées à l'avance dans MongoDB.

> 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"}]})

Le résultat de l'exécution est le suivant.

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

Essayez de voir que les données d'affichage sont modifiées en changeant le dernier argument pql.execute (requête PartiQl).

Les essais et erreurs suivants jusqu'à la création du PoC

Lorsque vous exécutez l'aide de partiql, il semble que vous puissiez également l'exécuter comme une commande autre que REPL comme indiqué ci-dessous.

$ ./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 

Il semble que vous puissiez effectuer une recherche par requête sur le shell en exécutant la commande suivante.

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

Il y a une déclaration ici que --input ne peut utiliser que le format ION. Pour ceux qui ne le savent pas ici, format ION est un format de sérialisation de données créé par Amazon, et est une description de format de texte de type JSON. De plus, il est écrit au format binaire. Module en Python est également fourni, vous pouvez donc convertir JSON ⇔ ION en l'utilisant.

>>> 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"}]}'

Lorsque vous enregistrez réellement le résultat de sortie sous test.ion et que vous l'exécutez, ce sera comme suit.

$ 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'
      }
    ]
  }
>>

Cependant, lorsque j'ai essayé quelques choses ici, lorsque j'ai entré des données imbriquées dans la clause from, un événement inattendu s'est produit dans lequel le résultat de sortie était vide. Ici, j'ai renoncé à poursuivre cette méthode.

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

Cependant, échanger le résultat de sortie de REPL en connectant PIPE avec le sous-processus Popen de Python n'est pas très propre en tant que code, nous allons donc envisager une autre méthode.

Il existe une méthode pour saisir les informations de la source de recherche de l'entrée ici avec l'option -e en plus de l'option -i. (Dans ce cas, les données à saisir seront des données au format original PartiQL, donc la conversion au format original JSON⇔PariQL est requise.) Cependant, avec les options -q et -e, les informations d'entrée sont écoutées à partir de l'entrée standard, donc lorsqu'elles sont exécutées, elles seront dans l'état d'attente d'entrée utilisateur. Enfin, en laissant l'option -i lire les données factices comme des données factices, l'objectif initial a été atteint.

Recommended Posts

J'ai essayé de jouer en connectant PartiQL et MongoDB
J'ai essayé de jouer avec l'image avec Pillow
J'ai essayé la différenciation jacobienne et partielle avec python
J'ai essayé la synthèse de fonctions et le curry avec python
J'ai essayé de jouer avec la calculatrice avec tkinter
[Introduction à AWS] J'ai essayé de porter une application de conversation et de jouer avec text2speech @ AWS ♪
J'ai essayé de lire et d'enregistrer automatiquement avec VOICEROID2 2
J'ai essayé d'implémenter et d'apprendre DCGAN avec PyTorch
J'ai essayé de lire et d'enregistrer automatiquement avec VOICEROID2
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
[Introduction à AWS] J'ai essayé de jouer avec la conversion voix-texte ♪
J'ai essayé de gratter avec Python
J'ai essayé le clustering avec PyCaret
J'ai essayé gRPC avec Python
J'ai essayé de gratter avec du python
J'ai essayé de prédire et de soumettre les survivants du Titanic avec Kaggle
J'ai essayé de connecter Raspeye et conect + avec l'API Web
[Introduction au modèle de maladie infectieuse] J'ai essayé de m'adapter et de jouer
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
J'ai affiché le chat de YouTube Live et essayé de jouer
J'ai essayé l'apprentissage automatique avec liblinear
J'ai essayé webScraping avec python.
J'ai essayé de déplacer de la nourriture avec SinGAN
J'ai essayé d'implémenter DeepPose avec PyTorch
J'ai essayé la détection de visage avec MTCNN
J'ai joué avec PyQt5 et Python3
J'ai essayé d'exécuter prolog avec python 3.8.2.
J'ai essayé la communication SMTP avec Python
J'ai essayé la génération de phrases avec GPT-2
J'ai essayé d'apprendre LightGBM avec Yellowbrick
J'ai essayé la reconnaissance faciale avec OpenCV
J'ai essayé de visualiser les signets volant vers Slack avec Doc2Vec et PCA
[Commerce système] J'ai essayé de jouer avec décomposer l'oscillateur stochastique avec python ♬
J'ai essayé l'expression des nombres naturels et le traitement arithmétique uniquement avec le traitement de liste
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé d'utiliser PyEZ et JSNAPy. Partie 4: Automatisez la configuration du FAI avec PyEZ et JSNAPy
J'ai essayé de créer des taureaux et des vaches avec un programme shell
J'ai essayé de détecter facilement les points de repère du visage avec python et dlib
J'ai essayé l'analyse de régression multiple avec régression polypoly
J'ai essayé d'envoyer un SMS avec Twilio
J'ai essayé d'utiliser Amazon SQS avec django-celery
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé linebot avec flacon (anaconda) + heroku
J'ai essayé de visualiser AutoEncoder avec TensorFlow
J'ai installé DSX Desktop et l'ai essayé
J'ai essayé de commencer avec Hy
J'ai essayé d'exprimer de la tristesse et de la joie face au problème du mariage stable.
J'ai essayé de jouer au jeu ○ ✕ en utilisant TensorFlow
J'ai essayé d'utiliser du sélénium avec du chrome sans tête
J'ai essayé l'analyse factorielle avec des données Titanic!
J'ai essayé d'apprendre avec le Titanic de Kaggle (kaggle②)
J'ai essayé le rendu non réaliste avec Python + opencv
J'ai essayé de convertir la chaîne datetime <-> avec tzinfo en utilisant strftime () et strptime ()
J'ai essayé la surveillance vivante (Ping) de Linux (CentOS 7) avec le serveur de surveillance Zabbix
J'ai essayé un langage fonctionnel avec Python
J'ai essayé d'apprendre l'angle du péché et du cos avec le chainer