Flask How do you use sqlalchemy declaratively with init_db ()?

this is my database.py

engine = create_engine('sqlite:///:memory:', echo=True) session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) Base = declarative_base() Base.query = session.query_property() def init_db(): # import all modules here that might define models so that # they will be registered properly on the metadata. Otherwise # you will have to import them first before calling init_db() import models Base.metadata.create_all(engine) 

and this is my backend.py

 from flask import Flask, session, g, request, render_template from database import init_db, session from models import * app = Flask(__name__) app.debug = True app.config.from_object(__name__) # Serve static file during debug if app.config['DEBUG']: from werkzeug import SharedDataMiddleware import os app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { '/': os.path.join(os.path.dirname(__file__), 'static') }) @app.route('/') def foo(): session.add(User()) session.commit() return "NOTHING HERE." if __name__ == "__main__": init_db() app.run(port=8888) 

I notice a couple of strange things:

  • When I do python backend.py , I see that tables are created twice . The same create table commands run
  • When I visit '/', I get the following error, even if I am 100% sure that the tables are created. Why?

cursor.execute (operator, parameters) OperationalError: (OperationalError) no such table: users u'INSERT INTO users DEFAULT VALUES '()

+6
source share
1 answer

When you create a SQLite database in memory, it is only available for the specific thread that created it - change create_engine('sqlite:///:memory:') to create_engine('sqlite:////some/file/path/db.sqlite' and your tables will exist.

As you can see the tables created twice - Flask in debug mode by default works with the server, which reboots every time the code changes. To do this, at startup, it starts a new process that actually starts the server, so before you start the server, the init_db function is init_db , and then called again when the server creates a child process to serve requests.

+8
source

Source: https://habr.com/ru/post/922342/


All Articles