Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

db.create_all() doesn't create tables defined in separate file

I am trying to create the tables for my models, which are defined in a separate module from my app. I call db.create_all(), but no tables are created and there are no errors. I've defined the models and imported them before calling create_all. Why doesn't this work?

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:123@localhost/flask'
db = SQLAlchemy(app)

from models import User

db.create_all()
db.session.commit()

models.py:

from flask.ext.sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
  __tablename__ = 'users'
  uid = db.Column(db.Integer, primary_key = True)
like image 203
user1592380 Avatar asked Jan 28 '16 15:01

user1592380


People also ask

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.

Does SQLAlchemy auto create table?

Creating and Inserting Data into Tables By passing the database which is not present, to the engine then sqlalchemy automatically creates a new database.

How do I create a database in flask-SQLAlchemy?

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

What is Sqlalchemy_track_modifications?

SQLALCHEMY_TRACK_MODIFICATIONS. If set to True , Flask-SQLAlchemy will track modifications of objects and emit signals. The default is None , which enables tracking but issues a warning that it will be disabled by default in the future. This requires extra memory and should be disabled if not needed.


1 Answers

You created two separate db instances, one along with the app and one along with the models. Each instance has it's own metadata that stores the tables defined on it. The one you're using to issue the create table statement was not the one that the models were defined on. You should use only one instance of the extension, importing it when needed.

myapp/__init__.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy(app)

# import the models *after* the db object is defined
from myapp import models

myapp/models.py:

from myapp import db

class User(db.Model):
    ...

create_tables.py:

from myapp import app, db

with app.app_context():
    db.create_all()

Other things to note:

  • You should structure your app as a package, so that everything is importable under one location.
  • flask.ext is deprecated, import the extension directly from its package name.
  • Flask-SQLAlchemy automatically generates __tablename__ from the class name, you don't need to define it yourself.
  • You do not have to call commit after create_all.
like image 70
davidism Avatar answered Oct 05 '22 02:10

davidism