2012-08-08 21 views
5

đây là database.py tôiBình làm thế nào để bạn sử dụng sqlalchemy declaratively với 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) 

và đây là 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) 

Tôi nhận thấy một vài điều kỳ lạ của tôi:

  1. Khi tôi làm python backend.py Tôi nhìn thấy các bảng đang được tạo hai lần. Các câu lệnh tạo bảng giống nhau được thực thi
  2. Khi tôi truy cập '/', tôi nhận được lỗi sau ngay cả khi tôi chắc chắn 100% rằng các bảng đã được tạo. Tại sao?

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

+0

Bạn cũng có thể đăng mã mô hình của mình không? Không chắc chính xác bạn đang cố gắng làm gì ở đây. Nói chung, bạn nên gọi tạo cơ sở dữ liệu (init_db) chỉ một lần. Tôi đề nghị ít nhất, lấy nó ra khỏi backend.py và chỉ gọi database.py một lần trước đây. – codegeek

Trả lời

8

Khi bạn tạo một cơ sở dữ liệu SQLite trong bộ nhớ nó chỉ là truy cập đến các chủ đề cụ thể mà tạo ra nó - thay đổi create_engine('sqlite:///:memory:')-create_engine('sqlite:////some/file/path/db.sqlite' và bảng của bạn sẽ tồn tại.

Là lý do tại sao bạn thấy các bảng được tạo hai lần - Bình thường trong chế độ gỡ lỗi theo mặc định sẽ chạy với máy chủ tải lại mỗi khi bạn thay đổi mã của mình. Để thực hiện khi nó bắt đầu, nó tạo ra một tiến trình mới thực sự chạy máy chủ - vì vậy hàm init_db của bạn được gọi trước khi bạn khởi động máy chủ, sau đó nó được gọi lại khi máy chủ tạo một tiến trình con để phục vụ các yêu cầu.

+1

Bạn nói đúng rằng cơ sở dữ liệu trong bộ nhớ là chuỗi cục bộ. Một cái nhìn sâu sắc quan trọng ở đây là: trong máy chủ phát triển của Flask, các trình xử lý tuyến đường chạy trong một luồng khác với luồng chính. Đó là lý do tại sao cùng một đối tượng 'db' thực sự đại diện cho các cơ sở dữ liệu khác nhau, tùy thuộc vào chủ đề mà nó được sử dụng. Tôi đã cố gắng để lưu ý điều này xuống đây: http://gehrcke.de/2015/05/in-memory-sqlite-database-and-flask-a-threading-trap/ –

Các vấn đề liên quan