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.
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.
Announcing PartiQL, one query language for your relational and non-relational data: https://t.co/ykrFrrOFEO pic.twitter.com/VN2FLJkvqN
— AWS Open Source (@AWSOpen) August 1, 2019
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.
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.
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).
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