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?
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()
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))
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