Flask和SQLAlchemy以及MetaData对象

时间:2012-11-18 13:32:36

标签: python sqlalchemy flask flask-sqlalchemy

这是我第一次使用这个环境。

我愿意使用的SQLAlchemy部分只允许我使用带有autoload = True的Table对象查询数据库。我这样做是因为我的表已经存在于DB(mysql服务器)中,并且不是通过定义flask模型创建的。

我已经完成了所有文档,但我似乎没有找到答案。这是一些代码:

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 个答案:

答案 0 :(得分:2)

您是否在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类。