SQLAlchemy - Obtendo uma lista de tabelas

94

Não consegui encontrar nenhuma informação sobre isso na documentação, mas como posso obter uma lista das tabelas criadas no SQLAlchemy?

Usei o método de classe para criar as tabelas.

sidewinder
fonte

Respostas:

86

Todas as tabelas são coletadas no tablesatributo do objeto SQLAlchemy MetaData. Para obter uma lista dos nomes dessas tabelas:

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

Se você estiver usando a extensão declarativa, provavelmente não está gerenciando os metadados sozinho. Felizmente, os metadados ainda estão presentes na classe base,

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

Se você está tentando descobrir quais tabelas estão presentes em seu banco de dados, mesmo entre aquelas sobre as quais você ainda não disse ao SQLAlchemy, então você pode usar a reflexão de tabela. SQLAlchemy irá então inspecionar o banco de dados e atualizar os metadados com todas as tabelas ausentes.

>>> metadata.reflect(engine)

Para Postgres, se você tiver vários esquemas, precisará fazer um loop por todos os esquemas no mecanismo:

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
fonte
7
Obsoleto desde a versão 0.8: Use o método sqlalchemy.schema.MetaData.reflect (). E observe, use em engine = sqlalchemy.create_engine('mysql://user:password@host/db_name')vez de "mysql://user:password@host"e engine.execute("use db_name").
Java Xu
@XuJiawan: Não tenho certeza de qual coisa está obsoleta aqui, não tenho certeza de qual método estou sugerindo se não for sqlalchemy.MetaData.reflect()?
SingleNegationElimination
@IfLoop: eu encontrei no documento sqlalchemy .
Java Xu de
1
@XuJiawan: O link sugere que o reflect argumento para MetaData.__init__, um sinalizador booleano, está obsoleto em favor do uso MetaData.reflect(), exatamente como mostrei em minha resposta.
SingleNegationElimination
2
@IfLoop: Sinto muito pelo meu péssimo inglês. Sua resposta está exatamente certa e eu a aumentei. Eu adicionei esse comentário apenas para que as pessoas percebam que, se usarem a versão <0,8, não podem usar o MetaData.reflect()método dessa forma. E também comente para outra pessoa que possa ter o mesmo problema causado pela declaração do motor.
Java Xu
77

Existe um método no engineobjeto para buscar o nome da lista de tabelas.engine.table_names()

Zubair Alam
fonte
eu recebo 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'(pilha truncada)
Darshan Chaudhary
Isso também funciona com Flask-SQLAlchemy , uma vez que há acesso direto ao mecanismo via eg DB.engine.table_names()ou qualquer que seja o nome da variável do banco de dados.
colidira
41
from sqlalchemy import create_engine
engine = create_engine('postgresql://use:pass@localhost/DBname')
print (engine.table_names())
Maeda
fonte
3
Esta é a resposta correta que funciona desde novembro de 2018.
Austin Mackillop
Se não funcionar, é mais provável que o mecanismo não possa se conectar corretamente (um problema na linha 2), mas você não receberá a mensagem de erro até executarengine.table_names()
grofte
Use esta resposta pessoas.
Manakin
12

Dentro do interpretador python, use db.engine.table_names ()

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

Eu estava procurando por algo parecido com isto:

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

Ele executa e retorna todas as tabelas.

atualizar:

Postgres:

eng = create_engine('postgresql+psycopg2://root:password@localhost/
q = eng.execute('SELECT * FROM pg_catalog.pg_tables')
jmunsch
fonte
3
Isso não é multiplataforma. Ele só funcionará com o mysql e não com outros mecanismos de banco de dados.
Edward Betts
@EdwardBetts você está certo, sobre qual mecanismo de banco de dados você estava se perguntando?
jmunsch
OP pediu postgres não sql
o elhajoui
4

O objeto de metadados com o qual você criou as tabelas tem isso em um dicionário.

metadata.tables.keys()
Keith
fonte
4

Estou resolvendo mesmo problema e encontrei este post. Depois de executar algumas tentativas, sugiro usar abaixo para listar todas as tabelas: (mencionado por zerocog)

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

Isso é útil para o manuseio direto da mesa e acho que é recomendado.

E use o código abaixo para obter os nomes das tabelas:

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

"metadata.tables" fornece um Dict para o nome da tabela e o objeto Table. o que também seria útil para uma consulta rápida.

user2189731
fonte
isto! sem o reflect, metadata.sorted_tablesnão funcionará
Kay,
2

Refletir todas as tabelas de uma vez permite que você recupere nomes de tabelas ocultos também. Eu criei algumas tabelas temporárias e elas apareceram com

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

Referência http://docs.sqlalchemy.org/en/latest/core/reflection.html

zerocog
fonte
2

Simples assim:

engine.table_names()

Além disso, para testar se existe uma tabela:

engine.has_table(table_name)
Han Zhang
fonte