2012-08-08 55 views
5

これは私のdatabase.pyFlaskどのようにsqlalchemyをinit_db()で宣言的に使用しますか?

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) 

です:私はpython backend.pyを行うと私は

  1. を作成されたテーブルを参照してください2回。同じcreate table文が実行されます
  2. 私が '/'にアクセスすると、テーブルが作成されたことを100%確信していても、次のエラーが発生します。どうして?

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

+0

モデルコードも投稿できますか?あなたがここで何をしようとしているのかはっきりしない。一般に、データベース作成(init_db)は1回だけ呼び出す必要があります。私は少なくとも、backend.pyから取り出して、一度だけdatabase.pyを呼び出すことをお勧めします。 – codegeek

答えて

8

あなたがメモリにSQLiteデータベースを作成するときには、それを作成し、特定のスレッドにのみアクセス可能である - create_engine('sqlite:////some/file/path/db.sqlite'に変更create_engine('sqlite:///:memory:')とあなたのテーブルが存在します。

テーブルが2回作成されているのはなぜですか?Flaskのデバッグモードは、デフォルトでコードを変更するたびにリロードするサーバーで実行されます。起動時には、実際にサーバーを実行する新しいプロセスが生成されるため、サーバーを起動する前にinit_db関数が呼び出された後、サーバーが要求を処理する子プロセスを作成するときに再度呼び出されます。

+1

メモリ内のデータベースがスレッドローカルであることは間違いありません。ここで重要なのは、Flaskの開発サーバーでは、ルートハンドラがメインスレッドとは異なるスレッドで実行されることです。そのため、同じ 'db'オブジェクトは実際にどのスレッドから使​​用されているかによって異なるデータベースを表します。私はここでこれをメモしようとしました:http://gehrcke.de/2015/05/in-memory-sqlite-database-and-flask-a-threading-trap/ –

関連する問題