2012-11-18 5 views
2

이 환경을 처음 사용합니다.Flask 및 SQLAlchemy와 MetaData 객체

SQLAlchemy에서 기꺼이 사용하려는 부분은 autoload = True로 테이블 개체를 사용하여 데이터베이스를 쿼리 할 수있는 부분입니다. 내 테이블이 이미 DB (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() 

이제 왜 글로벌 var라는 메타 데이터를 사용하는지 궁금해 할 수 있습니다. 확인 좀 더 코드 :

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

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

당신은 내가 함수 내에서 액세스하기 위해 세계로 그 객체가 필요 볼 수 있듯이.

또한 필요한 각 함수에서 동일한 var testTable을 선언하고 있습니다. 나는 이것이 올바른 접근 방식이 아니라고 생각합니다. 내 사례와 관련하여 모범 사례 조언을 찾지 못했습니다.

감사합니다.

답변

1

this snippet을 SQLAlchemy 문서에서 보았습니까?

아마이 작동합니다 :

# 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에 새 엔진을 만들 필요가 없습니다. 앱을 만드는 것이 더 적절한 장소입니다.

케이스가 매우 특별한 경우 요청 당 엔진이 1 대 필요할 수도 있습니다.이 경우 ThreadLocalMetaData 클래스를 고려해야합니다.

+0

'meta = MetaData()'를 사용 했습니까? 또한 SA 문서에 대한 링크가 더 이상 작동하지 않는다고 확신합니다. – cjauvin

+0

안녕하세요, 일부 경로에 대해 db 연결을 필요로하지 않으 셨다면 모든 "before_request"에 대해 전체 db 테이블을 반영하는 것이 중복됩니다. ? 어떻게 이것을 피할 수 있을까요? –

+0

데이터베이스 연결은 한 번만 수행해야합니다. 즉, 앱 인스턴스 또는 'before_request' 콜백이 아닌'before_first_request' 콜백에서 connect_db()를 호출해야합니다. 내 대답의 반영이 각 요청 전에가 아니라 첫 번째 요청 전에 만 발생하는지 확인합니다. –

관련 문제