web-dev-qa-db-fra.com

Comment créer une nouvelle base de données en utilisant SQLAlchemy?

En utilisant SQLAlchemy, un objet Engine est créé comme suit:

from sqlalchemy import create_engine
engine = create_engine("postgresql://localhost/mydb")

L’accès à engine échoue si la base de données spécifiée dans l’argument à create_engine _ (dans ce cas, mydb) n'existe pas. Est-il possible de dire à SQLAlchemy de créer une nouvelle base de données si la base de données spécifiée n'existe pas?

85
Anand Chitipothu

Sur postgres, trois bases de données sont normalement présentes par défaut. Si vous pouvez vous connecter en tant que superutilisateur (par exemple, le rôle postgres, vous pouvez alors vous connecter aux bases de données postgres ou template1. Le fichier par défaut pg_hba.conf permet uniquement à l'utilisateur unix nommé postgres d'utiliser le rôle postgres, aussi le plus simple est-il simplement de devenir cet utilisateur. Dans tous les cas, créez un moteur comme d'habitude avec un utilisateur disposant des autorisations nécessaires pour créer une base de données:

>>> engine = sqlalchemy.create_engine("postgres://postgres@/postgres")

Cependant, vous ne pouvez pas utiliser engine.execute(), car postgres ne vous permet pas de créer des bases de données à l'intérieur de transactions et que sqlalchemy tente toujours d'exécuter des requêtes dans une transaction. Pour résoudre ce problème, obtenez la connexion sous-jacente du moteur:

>>> conn = engine.connect()

Mais la connexion sera toujours dans une transaction, vous devez donc mettre fin à la transaction ouverte avec un commit:

>>> conn.execute("commit")

Et vous pouvez ensuite procéder à la création de la base de données en utilisant la commande PostgreSQL appropriée.

>>> conn.execute("create database test")
>>> conn.close()
87

SQLAlchemy-Utils fournit des types de données personnalisés et diverses fonctions utilitaires pour SQLAlchemy. Vous pouvez installer la version officielle la plus récente à l'aide de pip:

pip install sqlalchemy-utils

Les aides de base de données incluent un create_database une fonction:

from sqlalchemy import create_engine
from sqlalchemy_utils import database_exists, create_database

engine = create_engine("postgres://localhost/mydb")
if not database_exists(engine.url):
    create_database(engine.url)

print(database_exists(engine.url))
98
buhtz

Il est possible d'éviter la gestion manuelle des transactions lors de la création d'une base de données en fournissant isolation_level='AUTOCOMMIT' à create_engine une fonction:

import sqlalchemy

with sqlalchemy.create_engine(
    'postgresql:///postgres',
    isolation_level='AUTOCOMMIT'
).connect() as connection:
    connection.execute('CREATE DATABASE my_database')

De plus, si vous n'êtes pas sûr que la base de données n'existe pas, il existe un moyen d'ignorer les erreurs de création de base de données en supprimant sqlalchemy.exc.ProgrammingError exception:

import contextlib
import sqlalchemy.exc

with contextlib.suppress(sqlalchemy.exc.ProgrammingError):
    # creating database as above
6
renskiy