Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all models from flask-sqlalchemy db

After a database is constructed in SQLAlchemy, I want to get all of the models, which is to say, the classes which represent them

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

Can this be achieved? How?

I can get the tables decently, just not the models. Eg:

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

this gives the tables just not the models themselves

like image 731
corvid Avatar asked Oct 22 '14 18:10

corvid


People also ask

What does Flask-SQLAlchemy query return?

Flask-SQLAlchemy Query Returns the Database Class and the Data.

What does db Create_all () do?

Definition of SQLAlchemy create_all. Sqlalchemy create_all method is used to create a new table into the database. This method will first check whether the table exists in the database or not if suppose it has found an existing table it will not create any table.

Is Flask-SQLAlchemy the same as SQLAlchemy?

What is Flask-SQLAlchemy? Flask-SQLAlchemy is an extension for Flask that aims to simplify using SQLAlchemy with Flask by providing defaults and helpers to accomplish common tasks. One of the most sought after helpers being the handling of a database connection across the app.

How do you query a database in Flask?

You then create a Flask application instance called app , which you use to configure two Flask-SQLAlchemy configuration keys: SQLALCHEMY_DATABASE_URI : The database URI to specify the database you want to establish a connection with. In this case, the URI follows the format sqlite:/// path/to/database. db .


2 Answers

There are several related questions, but I didn't see any exact duplicates.

Using your code to get the table names, and this question's accepted answer to get the classes, we can match the classes to the tablenames that are registered on your database.

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

Where models is the list of models registed on your database.

The try catch is required because a <sqlalchemy.ext.declarative.clsregistry._ModuleMarker object> will be included in the for clazz in ... loop, and it doesn't have a __tablename__ attribute.

like image 78
Celeo Avatar answered Sep 22 '22 12:09

Celeo


In SQLAlchemy 1.4, the _decl_class_registry.values() method has removed, you can use db.Model.registry.mappers instead:

models = {
    mapper.class_.__name__: mapper.class_
    for mapper in db.Model.registry.mappers
}

See the details in this issue.

like image 36
Grey Li Avatar answered Sep 26 '22 12:09

Grey Li