2
votes

sqlite3: se connecter à une base de données dans le cloud (S3)

J'ai une petite base de données sqlite (110kb) dans un s3 s3. Je veux me connecter à cette base de données chaque fois que j'exécute mon application python .

Une option consiste simplement à télécharger la base de données chaque fois que j'exécute l'application python et que je la connecte normalement. Mais je veux savoir s'il existe un moyen de se connecter à cette base de données sqlite via la mémoire, en utilisant S3FileSystem et en l' open . sqlite3 bibliothèque sqlite3 et python 3.6


1 commentaires

4 Réponses :


4
votes

Non, il n'est pas possible de se connecter directement à une base de données sqlite stockée dans le cloud. Même si vous souhaitez héberger la base de données en mémoire, elle doit encore être téléchargée complètement avant d'être chargée en mémoire. Pour ce faire, il faut toujours que la base de données soit d'abord chargée à partir d'un fichier sur disque ou à l'aide de commandes DDL pour la créer directement en mémoire. À ma connaissance, il n'y a aucun moyen de charger un flux de données en tant que base de données en mémoire sqlite (voir Exemple 1: Chargement et enregistrement de bases de données en mémoire ).

Dans un tel scénario, une fois que la base de données a été déconnectée, il faudrait alors la retélécharger sur le stockage cloud. S3FileSystem.open renvoie simplement un flux de données. Tout ce que le flux vous permettra de faire est de télécharger le fichier dans un magasin local afin qu'il puisse être ouvert / manipulé localement.

Si vous avez vraiment besoin d'une base de données cloud, vous devez rechercher un autre type de base de données hébergée.


1 commentaires

Voici une autre réponse qui donne plus d'informations sur le but de sqlite.



6
votes

Comme d'autres réponses l'indiquent, vous ne souhaitez probablement pas utiliser SQLite comme base de données principale dans le cloud.

Cependant, dans le cadre d'un projet parallèle amusant, j'ai écrit un connecteur de source de données Amazon Athena qui vous permet d'interroger des bases de données SQLite dans S3 à partir d'Athena . Pour ce faire, j'ai écrit une interface SQLite en lecture seule pour S3.

SQLite a un concept d' interface OS ou VFS . À l'aide d'un wrapper Python SQLite appelé APSW , vous pouvez écrire une implémentation VFS pour des systèmes de fichiers arbitraires. C'est ce que j'ai fait dans mon projet et j'ai inclus l'implémentation ci-dessous.

Pour l'utiliser, vous devez d'abord enregistrer le VFS, puis créer une nouvelle connexion SQLite avec cette implémentation comme pilote.

Je dois noter que cela n'est pas du tout optimisé, il faudra donc probablement toujours lire des bases de données complètes à partir de S3 en fonction de vos requêtes. Mais cela ne semble pas être un problème dans ce cas précis.

import apsw
import sys
import boto3

VFS_S3_CLIENT = boto3.client('s3')


class S3VFS(apsw.VFS):
    def __init__(self, vfsname="s3", basevfs=""):
        self.vfsname=vfsname
        self.basevfs=basevfs
        apsw.VFS.__init__(self, self.vfsname, self.basevfs)

    def xOpen(self, name, flags):
        return S3VFSFile(self.basevfs, name, flags)


class S3VFSFile():
    def __init__(self, inheritfromvfsname, filename, flags):
        self.bucket = filename.uri_parameter("bucket")
        self.key = filename.filename().lstrip("/")
        print("Initiated S3 VFS for file: {}".format(self._get_s3_url()))

    def xRead(self, amount, offset):
        response = VFS_S3_CLIENT.get_object(Bucket=self.bucket, Key=self.key, Range='bytes={}-{}'.format(offset, offset + amount))
        response_data = response['Body'].read()
        return response_data

    def xFileSize(self):
        client = boto3.client('s3')
        response = client.head_object( Bucket=self.bucket, Key=self.key)
        return response['ContentLength']

    def xClose(self):
        pass

    def xFileControl(self, op, ptr):
        return False

    def _get_s3_url(self):
        return "s3://{}/{}".format(self.bucket, self.key)

Une fois que vous avez le curseur, vous pouvez exécuter des instructions SQL standard comme ceci:

for x,y,z in cursor.execute("select x,y,z from foo"):
    print (cursor.getdescription())  # shows column names and declared types
    print (x,y,z)

Implémentation VFS (nécessite la bibliothèque APSW et boto3 pour la connectivité S3)

S3FS = S3VFS()  # S3VFS defined below

# This odd format is used due to SQLite requirements
sqlite_uri = "file:/{}/{}.sqlite?bucket={}&immutable=1".format(
  S3_PREFIX,
  DATABASE_NAME,
  S3_BUCKET
)

connection = apsw.Connection(sqlite_uri,
  flags=apsw.SQLITE_OPEN_READONLY | apsw.SQLITE_OPEN_URI,
  vfs=S3FS.vfsname
)
cursor = connection.cursor()


0 commentaires

0
votes

si toutes vos actions sont limitées dans la lecture de SQLite, je suppose que c'est possible. Mais je n'ai aucune idée si l'écriture est également possible. dans mon cas, j'utilise gdal (nécessite libgdal) et gdal / vsis3, / vsis3-streaming (basé sur / vsicurl) vous donne la possibilité de lire SQLite et de nombreuses autres sources de données à partir du cloud. si vous souhaitez utiliser SQLite brut plutôt que basé sur la couche de source de données de gdal, vous pouvez simplement les écrire dans votre base de données locale via l'API de gdal, mais si oui, pourquoi ne pas simplement le télécharger et le lire?

pour moi, puisque je travaille sur des données spatiales et que DataSource de gdal fournit de nombreuses API pour manipuler les données spatiales, cette méthode fonctionne très bien. Je suis toujours à la recherche d'un bon moyen d'écrire sur un SQLite basé sur le cloud.

Pour info, voici le document du système de fichiers virtuel gdal https://gdal.org/user/virtual_file_systems.html


0 commentaires

0
votes

Oui, c'est possible avec EFS:

https://www.lambrospetrou.com/articles/aws-lambda-and-sqlite-over-efs/

AWS a récemment publié une intégration entre AWS Lambda et Amazon EFS. Il prend en charge la mise à niveau / rétrogradation du verrou NFSv4 qui est nécessaire à SQLite. Cela signifie que le moteur SQLite peut avoir un accès en lecture / écriture aux fichiers stockés sur le système de fichiers EFS.


0 commentaires