简体   繁体   中英

SQLAlchemy create_all() unable to create new tables

I have flask web app which uses mysql db using flask-sqlalchemy.

I have kept separate utility scripts for DDL creation.

My existing app works perfectly fine but this script is unable to create new table.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import connect_strng
    
app = Flask(__name__)
    
app.config['SQLALCHEMY_DATABASE_URI'] = connect_string

db = SQLAlchemy()

# Added this import just before create_all
from db_models import Test

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

I have defined model inside db_models

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Test(db.Model):
    __tablename__ = 'test'
    
    test_id = db.Column(db.Integer, primary_key=True)
    

My script is finishing with exit code of 0 indicating no errors, but I don't see table getting generated in mysql database.

$ python create_table.py 
$ echo $?
0

I checked answer to the similar question but did not work.

You need to use the same db object across your whole app. Importing it where it is needed.

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy() # <--- This is what is causing your issue
# IT should look something more like...
from create_table import db


class Test(db.Model):
    __tablename__ = 'test'
    
    test_id = db.Column(db.Integer, primary_key=True)

However there is a problem with the above suggestion...It will lead to a circular import. To solve that requires restructuring your app a bit. Exactly how to do it is up to you but I'll give you a suggestion.

Create a new file called database.py and put your db object in there. Then you can do from database import db whenever you need db .

database.py

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

As far as how to structure your app, consider the application factory pattern. It takes into account the circular import issue that commonly arises with flask.

I was able to resolve the issue by making use of flask's application context .

As sugested by @noslenkwah, you should use db object from single place by defining into single file database.py .

Here is my solution.

database.py

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

db_models.py

from database import db

class Test(db.Model):
    __tablename__ = 'test'
    
    test_id = db.Column(db.Integer, primary_key=True)

create_table.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import connect_strng
from database import db
    
app = Flask(__name__)
    
app.config['SQLALCHEMY_DATABASE_URI'] = connect_string


with app.app_context():
    db.init_app(app)
    # Added this import just beore create_all
    from db_models import Test, CrawlStat
    db.create_all()
    db.session.commit()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM