SQLAlchemy - Obtenir une liste de tables


94

Je n'ai trouvé aucune information à ce sujet dans la documentation, mais comment puis-je obtenir une liste des tables créées dans SQLAlchemy?

J'ai utilisé la méthode de classe pour créer les tables.

Réponses:


86

Toutes les tables sont collectées dans l' tablesattribut de l'objet SQLAlchemy MetaData. Pour obtenir une liste des noms de ces tables:

>>> metadata.tables.keys()
['posts', 'comments', 'users']

Si vous utilisez l'extension déclarative, vous ne gérez probablement pas vous-même les métadonnées. Heureusement, les métadonnées sont toujours présentes sur la classe de base,

>>> Base = sqlalchemy.ext.declarative.declarative_base()
>>> Base.metadata
MetaData(None)

Si vous essayez de déterminer quelles tables sont présentes dans votre base de données, même parmi celles dont vous n'avez même pas encore parlé à SQLAlchemy, vous pouvez utiliser la réflexion de table. SQLAlchemy inspectera ensuite la base de données et mettra à jour les métadonnées avec toutes les tables manquantes.

>>> metadata.reflect(engine)

Pour Postgres, si vous avez plusieurs schémas, vous devrez parcourir tous les schémas du moteur:

from sqlalchemy import inspect
inspector = inspect(engine)
schemas = inspector.get_schema_names()

for schema in schemas:
    print("schema: %s" % schema)
    for table_name in inspector.get_table_names(schema=schema):
        for column in inspector.get_columns(table_name, schema=schema):
            print("Column: %s" % column)

7
Obsolète depuis la version 0.8: veuillez utiliser la méthode sqlalchemy.schema.MetaData.reflect (). Et remarquez, utilisez engine = sqlalchemy.create_engine('mysql://user:password@host/db_name')plutôt que "mysql://user:password@host"et engine.execute("use db_name").
Java Xu

@XuJiawan: Je ne sais pas quelle chose est obsolète ici, je ne sais pas quelle méthode je suggère si ce n'est pas le cas sqlalchemy.MetaData.reflect()?
SingleNegationElimination

@IfLoop: Je l'ai trouvé dans le document sqlalchemy .
Java Xu

1
@XuJiawan: Le lien suggère que l' reflect argument to MetaData.__init__, un drapeau booléen, est déconseillé au profit de l'utilisation MetaData.reflect(), exactement comme je l'ai montré dans ma réponse.
SingleNegationElimination

2
@IfLoop: Je suis vraiment désolé pour mon mauvais anglais. Votre réponse est exactement la bonne et je l'ai augmentée. J'ai ajouté ce commentaire juste pour que les gens remarquent que s'ils utilisent la version <0.8, ils ne peuvent pas utiliser la MetaData.reflect()méthode de cette manière. Et commentez-le également pour quelqu'un d'autre qui pourrait avoir le même problème causé par la déclaration du moteur.
Java Xu

78

Il existe une méthode dans l' engineobjet pour récupérer le nom de la liste des tables.engine.table_names()


i get Traceback (most recent call last): File "dedup_jobs.py", line 31, in <module> print(engine.table_names()) File "/Users/darshanchoudhary/.virtualenvs/services/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2128, in table_names return self.dialect.get_table_names(conn, schema) value = value.replace(self.escape_quote, self.escape_to_quote) AttributeError: 'NoneType' object has no attribute 'replace'(pile tronquée)
Darshan Chaudhary

Cela fonctionne également avec Flask-SQLAlchemy , car il y a un accès direct au moteur via par exemple DB.engine.table_names()ou quel que soit le nom de la variable de base de données.
colidyre

42
from sqlalchemy import create_engine
engine = create_engine('postgresql://use:pass@localhost/DBname')
print (engine.table_names())

3
C'est la bonne réponse qui fonctionne à partir de novembre 2018.
Austin Mackillop

Si cela ne fonctionne pas, c'est probablement parce que le moteur ne peut pas se connecter correctement (donc un problème à la ligne 2) mais vous n'obtiendrez pas le message d'erreur jusqu'à ce que vous engine.table_names()
exécutiez

Utilisez cette réponse aux gens.
Manakin le

12

Dans l'interpréteur python, utilisez db.engine.table_names ()

$ python
>>> from myapp import db
>>> db.engine.table_names()

11

Je cherchais quelque chose comme ça:

from sqlalchemy import create_engine
eng = create_engine('mysql+pymysql://root:password@localhost:3306', pool_recycle=3600)
q = eng.execute('SHOW TABLES')

available_tables = q.fetchall()

Il exécute et renvoie toutes les tables.

mettre à jour:

Postgres:

eng = create_engine('postgresql+psycopg2://root:password@localhost/
q = eng.execute('SELECT * FROM pg_catalog.pg_tables')

3
Ce n'est pas multiplateforme. Cela ne fonctionnera qu'avec mysql, cela ne fonctionnera pas avec d'autres moteurs de base de données.
Edward Betts

@EdwardBetts vous avez raison, quel moteur de base de données vous demandiez-vous?
jmunsch

OP a demandé des postgres pas SQL
o elhajoui

4

L'objet de métadonnées avec lequel vous avez créé les tables a cela dans un dictionnaire.

metadata.tables.keys()

4

Je résous le même problème et j'ai trouvé ce post. Après quelques essais, je suggérerais d'utiliser ci-dessous pour lister toutes les tables: (mentionné par zerocog)

metadata = MetaData()
metadata.reflect(bind=engine)
for table in metadata.sorted_tables:
    print(table)

Ceci est utile pour la gestion directe des tables et je pense que c'est recommandé.

Et utilisez le code ci-dessous pour obtenir les noms de table:

for table_name in engine.table_names():
    print(table_name)

"metadata.tables" fournit un Dict pour le nom de la table et l'objet Table. ce qui serait également utile pour une requête rapide.


ce! sans le reflect, metadata.sorted_tablesne fonctionnera pas
Kay


2

Juste ce simple:

engine.table_names()

Aussi, pour tester si une table existe:

engine.has_table(table_name)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.