SQLAlchemy: obtener una lista de tablas

94

No pude encontrar ninguna información sobre esto en la documentación, pero ¿cómo puedo obtener una lista de tablas creadas en SQLAlchemy?

Usé el método de clase para crear las tablas.

sidewinder
fuente

Respuestas:

86

Todas las tablas se recopilan en el tablesatributo del objeto SQLAlchemy MetaData. Para obtener una lista de los nombres de esas tablas:

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

Si está utilizando la extensión declarativa, probablemente no esté administrando los metadatos usted mismo. Afortunadamente, los metadatos todavía están presentes en la clase base,

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

Si está tratando de averiguar qué tablas están presentes en su base de datos, incluso entre las que aún no le ha dicho a SQLAlchemy, puede usar la reflexión de tabla. Luego, SQLAlchemy inspeccionará la base de datos y actualizará los metadatos con todas las tablas que faltan.

>>> metadata.reflect(engine)

Para Postgres, si tiene varios esquemas, deberá recorrer todos los esquemas en el motor:

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
fuente
7
En desuso desde la versión 0.8: utilice el método sqlalchemy.schema.MetaData.reflect (). Y observe, use en engine = sqlalchemy.create_engine('mysql://user:password@host/db_name')lugar de "mysql://user:password@host"y engine.execute("use db_name").
Java Xu
@XuJiawan: No estoy seguro de qué cosa está desaprobada aquí, no estoy seguro de qué método estoy sugiriendo si no es así sqlalchemy.MetaData.reflect().
SingleNegationElimination
@IfLoop: Lo encontré en el documento sqlalchemy .
Java Xu
1
@XuJiawan: El enlace sugiere que el reflect argumento to MetaData.__init__, una bandera booleana, está en desuso a favor de su uso MetaData.reflect(), exactamente como lo he mostrado en mi respuesta.
SingleNegationElimination
2
@IfLoop: Lo siento mucho por mi pobre inglés. Tu respuesta es exactamente correcta y la he mejorado. Agregué ese comentario solo para que las personas noten que si usan la versión <0.8, es posible que no usen el MetaData.reflect()método de esta manera. Y también comentarlo para alguien más que pueda tener el mismo problema causado por la declaración del motor.
Java Xu
78

Hay un método en el engineobjeto para obtener el nombre de la lista de tablas.engine.table_names()

Zubair Alam
fuente
obtengo 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'(pila truncada)
Darshan Chaudhary
Esto también funciona con Flask-SQLAlchemy , ya que hay acceso directo al motor a través de , por ejemplo, DB.engine.table_names()o cualquiera que sea el nombre de la variable de la base de datos.
colidyre
42
from sqlalchemy import create_engine
engine = create_engine('postgresql://use:pass@localhost/DBname')
print (engine.table_names())
Maeda
fuente
3
Esta es la respuesta correcta que funciona a partir de noviembre de 2018.
Austin Mackillop
Si no funciona, lo más probable es que el motor no se pueda conectar correctamente (por lo que hay un problema en la línea 2), pero no recibirá el mensaje de error hasta que lo ejecuteengine.table_names()
grofte
Utilice esta respuesta personas.
Manakin
12

Dentro del intérprete de Python, use db.engine.table_names ()

$ python
>>> from myapp import db
>>> db.engine.table_names()
Mwirabua Tim
fuente
11

Estaba buscando algo como esto:

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

Realiza una ejecución y devuelve todas las tablas.

actualizar:

Postgres:

eng = create_engine('postgresql+psycopg2://root:password@localhost/
q = eng.execute('SELECT * FROM pg_catalog.pg_tables')
jmunsch
fuente
3
Esto no es multiplataforma. Solo funcionará con mysql, no funcionará con otros motores de base de datos.
Edward Betts
@EdwardBetts tienes razón, ¿qué motor de base de datos te estabas preguntando?
jmunsch
OP pidió postgres no sql
o elhajoui
4

El objeto de metadatos con el que creó las tablas tiene eso en un diccionario.

metadata.tables.keys()
Keith
fuente
4

Estoy resolviendo el mismo problema y encontré esta publicación. Después de intentarlo, sugeriría usarlo a continuación para enumerar todas las tablas: (mencionado por zerocog)

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

Esto es útil para el manejo directo de la mesa y creo que se recomienda.

Y use el siguiente código para obtener nombres de tablas:

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

"metadata.tables" proporciona un Dict para el nombre de la tabla y el objeto de la tabla. que también sería útil para consultas rápidas.

usuario2189731
fuente
¡esta! sin el reflect, metadata.sorted_tablesno funcionará
Kay
2

Reflejar todas las tablas a la vez le permite recuperar nombres de tablas ocultos también. Creé algunas tablas temporales y aparecieron con

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

Referencia http://docs.sqlalchemy.org/en/latest/core/reflection.html

zerocog
fuente
2

Así de simple:

engine.table_names()

Además, para probar si existe una tabla:

engine.has_table(table_name)
Han Zhang
fuente