Flask如何使用init_db()以声明方式使用sqlalchemy?

时间:2012-08-08 08:42:25

标签: python sqlalchemy flask

这是我的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)

这是我的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)

我注意到一些奇怪的事情:

  1. 当我python backend.py时,我看到正在创建的表格两次。执行相同的create table语句
  2. 当我访问'/'时,即使我100%确定已创建表,我也会收到以下错误。为什么?
  3.   

    cursor.execute(statement,parameters)OperationalError:   (OperationalError)没有这样的表:用户u'INSERT INTO用户DEFAULT   VALUES'()

1 个答案:

答案 0 :(得分:9)

当您在内存中创建SQLite数据库时,只有创建它的特定线程才能访问它 - 将create_engine('sqlite:///:memory:')更改为create_engine('sqlite:////some/file/path/db.sqlite'并且您的表将存在。

至于为何看到创建两次的表 - 默认情况下,调试模式下的Flask与每次更改代码时重新加载的服务器一起运行。为了在启动时执行,它会生成一个实际运行服务器的新进程 - 因此在启动服务器之前调用init_db函数,然后在服务器创建子进程来处理请求时再次调用它。