SQLAlchemy - Pobieranie listy tabel


97

Nie mogłem znaleźć żadnych informacji na ten temat w dokumentacji, ale jak mogę uzyskać listę tabel utworzonych w SQLAlchemy?

Do tworzenia tabel użyłem metody class.

Odpowiedzi:


89

Wszystkie tabele są gromadzone w tablesatrybucie obiektu SQLAlchemy MetaData. Aby uzyskać listę nazw tych tabel:

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

Jeśli używasz deklaratywnego rozszerzenia, prawdopodobnie nie zarządzasz samodzielnie metadanymi. Na szczęście metadane są nadal obecne w klasie bazowej,

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

Jeśli próbujesz dowiedzieć się, jakie tabele są obecne w Twojej bazie danych, nawet te, o których jeszcze nie powiedziałeś SQLAlchemy, możesz użyć odbicia tabel. SQLAlchemy następnie sprawdzi bazę danych i zaktualizuje metadane o wszystkie brakujące tabele.

>>> metadata.reflect(engine)

W przypadku Postgres, jeśli masz wiele schematów, musisz przejść przez wszystkie schematy w silniku:

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)

8
Przestarzałe od wersji 0.8: użyj metody sqlalchemy.schema.MetaData.reflect (). I zauważ, użyj engine = sqlalchemy.create_engine('mysql://user:password@host/db_name')zamiast "mysql://user:password@host"i engine.execute("use db_name").
Java Xu

@XuJiawan: Nie jestem pewien, która rzecz jest tutaj przestarzała, nie jestem pewien, którą metodę sugeruję, jeśli nie jest sqlalchemy.MetaData.reflect()?
SingleNegationElimination

@IfLoop: znalazłem to w dokumencie sqlalchemy .
Java Xu

1
@XuJiawan: Link sugeruje, że reflect argument do MetaData.__init__, flaga boolowska, jest przestarzały na rzecz używania MetaData.reflect(), dokładnie tak, jak pokazałem w mojej odpowiedzi.
SingleNegationElimination

2
@IfLoop: Bardzo przepraszam za mój słaby angielski. Twoja odpowiedź jest dokładnie poprawna, a ja ją poprawiłem. Dodałem ten komentarz, aby ludzie zauważyli, że jeśli używają wersji <0.8, to mogą nie używać MetaData.reflect()metody w ten sposób. A także skomentuj to dla kogoś, kto może mieć ten sam problem spowodowany deklaracją silnika.
Java Xu

82

W engineobiekcie znajduje się metoda pobierania listy nazw tabel.engine.table_names()


dostaję 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'(obcięty stos)
Darshan Chaudhary

Działa to również z Flask-SQLAlchemy , ponieważ istnieje bezpośredni dostęp do silnika poprzez np. DB.engine.table_names()Lub jakąkolwiek nazwę zmiennej bazy danych.
colidyre

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

3
To jest poprawna odpowiedź, która działa od listopada 2018 r.
Austin Mackillop

Jeśli to nie działa, to najprawdopodobniej dlatego, że silnik nie może się poprawnie połączyć (więc problem w linii 2), ale nie otrzymasz komunikatu o błędzie, dopóki nie uruchomiszengine.table_names()
grofte

Użyj tej odpowiedzi ludzie.
Manakin

Świetny! proste i działające tak dobrze
Soubinan

12

W interpreterze Pythona użyj db.engine.table_names ()

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

10

Szukałem czegoś takiego:

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

Wykonuje polecenie i zwraca wszystkie tabele.

aktualizacja:

Postgres:

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

3
To nie jest wieloplatformowa. Będzie działać tylko z mysql, nie będzie działać z innymi silnikami baz danych.
Edward Betts,

@EdwardBetts masz rację, nad jakim silnikiem db się zastanawiałeś?
jmunsch

OP poprosił o postgres, a nie sql
o elhajoui

5

Obiekt metadanych, za pomocą którego utworzyłeś tabele, ma to w słowniku.

metadata.tables.keys()

4

Rozwiązuję ten sam problem i znalazłem ten post. Po kilku próbach uruchomienia sugerowałbym użycie poniżej, aby wyświetlić wszystkie tabele: (wspomniane przez zerocog)

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

Jest to przydatne do bezpośredniej obsługi stołu i uważam, że jest zalecane.

I użyj poniższego kodu, aby uzyskać nazwy tabel:

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

„metadata.tables” zawiera Dict dla nazwy tabeli i obiektu Table. co byłoby również przydatne w przypadku szybkiego zapytania.


to! bez reflect, metadata.sorted_tablesnie zadziała
Kay


2

Po prostu takie proste:

engine.table_names()

Aby sprawdzić, czy tabela istnieje:

engine.has_table(table_name)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.