2012-11-18 43 views
2

這是我第一次使用這個環境。Flask和SQLAlchemy和MetaData對象

我願意使用的SQLAlchemy的部分只是允許我用autoload = True使用Table對象查詢數據庫的部分。我這樣做是因爲我的表已經存在於數據庫(MySQL服務器)中,並沒有通過定義瓶型來創建。

我已經通過了所有的文件,我似乎沒有找到答案。這裏是一些代碼:

app = Flask(__name__) 
app.config.from_object(__name__) 

metadata = None 

def connect_db(): 
    engine = create_engine(app.config['DATABASE_URI']) 
    global metadata 
    metadata = MetaData(bind=engine) 
    return engine.connect() 


@app.before_request 
def before_request(): 
    g.db = connect_db() 


@app.teardown_request 
def teardown_request(exception): 
    g.db.close() 

現在你可能想知道爲什麼我使用全局變量名爲元數據。確定一些更多的代碼:

@app.route('/test/<int:id>') 
def test(test_result_id): 

    testTable = Table('test_table', metadata , autoload=True) 

正如你所看到的,我需要該對象是全局的,才能從函數內部訪問它。

另外我聲明相同的var testTable在每個需要它的函數中。我覺得這不是正確的做法。我沒有找到像我這樣的案例的最佳實踐建議。

謝謝大家!

回答

1

您是否在SQLAlchemy文檔中看到過this snippet

也許這會工作:

# This is fine as a global global 
metadata = MetaData() 

@app.before_first_request 
def autoload_tables(): 
    meta.reflect(bind=g.db.bind) 

@app.route('/') 
def index(): 
    users_table = meta.tables['users'] 

這樣,你的表是反映每個進程只有一次,這可能是你想要的。請注意,您的引擎也應該是全局的,因此您不需要在@ app.before_request中創建新引擎 - 創建應用程序是更合適的地方。

如果您的情況非常特殊,您可能需要每個請求一個引擎,在這種情況下,您應該考慮ThreadLocalMetaData類。

+0

你是不是指'meta = MetaData()'?另外,我不確定鏈接到SA文檔的工作了.. – cjauvin

+0

嗨jd,如果某些路由,我們不需要一個數據庫連接,然後反映每個「before_request」整個數據庫表是多餘的權利?我們如何避免這種情況? –

+0

與數據庫的連接應該只進行一次,即應該在應用程序實例化或'before_first_request'回調(而不是'before_request')中調用connect_db()。請注意,我的回答中的反映是在第一個請求之前發生的,而不是在每個請求之前。 –