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.

sidewinder
la source

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)
SingleNegationElimination
la source
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()

Zubair Alam
la source
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())
Maeda
la source
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()
Mwirabua Tim
la source
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')
Jmunsch
la source
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()
Keith
la source
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.

user2189731
la source
ce! sans le reflect, metadata.sorted_tablesne fonctionnera pas
Kay
2

Reflecting All Tables at Once vous permet également de récupérer les noms de table masqués. J'ai créé des tables temporaires et elles sont apparues avec

meta = MetaData()
meta.reflect(bind=myengine)
for table in reversed(meta.sorted_tables):
    print table

Référence http://docs.sqlalchemy.org/en/latest/core/reflection.html

zerocog
la source
2

Juste ce simple:

engine.table_names()

Aussi, pour tester si une table existe:

engine.has_table(table_name)
Han Zhang
la source