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.

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)

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


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

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

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

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

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.


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


2

Simples assim:

engine.table_names()

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

engine.has_table(table_name)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.