2014-10-22 12 views
7

Po baza danych jest skonstruowany w SQLAlchemy, chcę uzyskać wszystkie modele, to znaczy, zajęcia, które ich reprezentująUzyskaj wszystkie modele od kolby-sqlalchemy db

>>> db 
<SQLAlchemy engine='postgresql:///example'> 
>>> ??? 
[<db.Model 'User'>, <db.Model 'Comment'>, <db.Model 'Article'>] 

można to osiągnąć? W jaki sposób?

Mogę dostać przyzwoite stoły, tylko nie modele. Np:

>>> for t in db.metadata.tables.items(): 
     print(t) 

daje tabele tylko nie same modele

Odpowiedz

7

Istnieje kilka powiązanych pytania, ale nie widzę żadnych dokładnych duplikatów.

Za pomocą swojego kodu, aby uzyskać nazwy tabel i zaakceptowaną odpowiedź this question, aby uzyskać klasy, możemy dopasować klasy do nazw tablic zarejestrowanych w bazie danych.

classes, models, table_names = [], [], [] 
for clazz in db.Model._decl_class_registry.values(): 
    try: 
     table_names.append(clazz.__tablename__) 
     classes.append(clazz) 
    except: 
     pass 
for table in db.metadata.tables.items(): 
    if table[0] in table_names: 
     models.append(classes[table_names.index(table[0])]) 

Gdzie models to lista modeli zarejestrowanych w bazie danych.

Połów próbny jest wymagany, ponieważ <sqlalchemy.ext.declarative.clsregistry._ModuleMarker object> zostanie zawarty w pętli for clazz in ... i nie ma atrybutu __tablename__.

0

działa to w moim przypadku: nieco krócej; bardziej czytelny

models = [] 
for name, thing in db_table_creation.__dict__.iteritems(): 
    if isinstance(thing, sqlalchemy.ext.declarative.DeclarativeMeta) and hasattr(thing, '__tablename__'): 
     models.append(thing) 
+2

Skąd pochodzi dB_table_creation – codyc4321

3

Jeśli potrzebujesz tylko klas, istnieje prostsze rozwiązanie. Wpadłem na niego na podstawie Celeo’s answer:

from flask import current_app 

# This is to be generic (ie. no need to pass your actual SQLAlchemy instance) 
# This way you can include it even in your own extension. 
db = current_app.extensions['sqlalchemy'].db 

[cls for cls in db.Model._decl_class_registry.values() 
if isinstance(cls, type) and issubclass(cls, db.Model)] 

nie potrzebujesz wszystkich tych dodatkowych zmiennych pomocniczych, po prostu pyta rejestru klasy i odfiltrowuje wszystko, co nie jest modelką.