Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Flask-SQLAlchemy create_all discover the models to create?

Flask-SQLAlchemy's db.create_all() method creates each table corresponding to my defined models. I never instantiate or register instances of the models. They're just class definitions that inherit from db.Model. How does it know which models I have defined?

like image 785
Alex Pana Avatar asked Jun 26 '15 21:06

Alex Pana


People also ask

How does SQLAlchemy Flask work?

It provides ways to interact with several database engines such as SQLite, MySQL, and PostgreSQL. It gives you access to the database's SQL functionalities. It also gives you an Object Relational Mapper (ORM), which allows you to make queries and handle data using simple Python objects and methods.

What does db Create_all () do?

Creating and Dropping Database Tables create_all() creates foreign key constraints between tables usually inline with the table definition itself, and for this reason it also generates the tables in order of their dependency.

How does SQLAlchemy connect to Flask?

Step 1 − Install Flask-SQLAlchemy extension. Step 2 − You need to import SQLAlchemy class from this module. Step 3 − Now create a Flask application object and set URI for the database to be used. Step 4 − Then create an object of SQLAlchemy class with application object as the parameter.


2 Answers

Flask-SQLAlchemy does nothing special, it's all a standard part of SQLAlchemy.

Calling db.create_all eventually calls db.Model.metadata.create_all. Tables are associated with a MetaData instance as they are defined. The exact mechanism is very circuitous within SQLAlchemy, as there is a lot of behind the scenes bookkeeping going on, so I've greatly simplified the explanation.

db.Model is a declarative base class, which has some special metaclass behavior. When it is defined, it creates a MetaData instance internally to store the tables it generates for the models. When you subclass db.Model, its metaclass behavior records the class in db.Model._decl_class_registry as well as the table in db.Model.metadata.


Classes are only defined when the modules containing them are imported. If you have a module my_models written somewhere, but it is never imported, its code never executes so the models are never registered.

This may be where some confusion about how SQLAlchemy detects the models comes from. No modules are "scanned" for subclasses, db.Model.__subclasses__ is not used, but importing the modules somewhere is required for the code to execute.

  1. Module containing models is imported and executed.
  2. Model class definition is executed, subclasses db.Model
  3. Model's table is registered with db.Model.metadata
like image 76
davidism Avatar answered Sep 17 '22 21:09

davidism


You need to call create_all() in the same module as all the models are in. If they are in separate modules, you need to import them all before calling create_all(). SQLAlchemy looks at what models have been subclassed from db.Model, and it will only see models that have been imported. It will create the corresponding table for each model. Also explained here.

like image 25
Lawrence Benson Avatar answered Sep 17 '22 21:09

Lawrence Benson