无法在Pyramid应用中将元数据绑定到SQLAlchemy引擎

-1 投票
2 回答
1032 浏览
提问于 2025-04-18 16:08

有人能告诉我为什么这个不工作吗:

我的 init.py 文件:

from pyramid.config import Configurator
from pyramid_jinja2 import renderer_factory
from sqlalchemy import engine_from_config

from .models import (DBSession, 
                Base,
                )

def main(global_config, **settings):
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind = engine)
    Base.metadata.bind = engine

    config = Configurator(settings = settings)
    config.include('pyramid_jinja2')

    #The views/routes are added here
    config.add_static_view('static', 'static')
    config.add_static_view('scripts', 'scripts')

    config.add_route("my_route", '/')
    config.add_route("sign_in", "/sign_in")
    config.add_route("sign_up", "/sign_up")
    config.add_route("main_page", "/{username}")
    config.scan()

    return config.make_wsgi_app()

我的 models.py 文件:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.schema import Table
from sqlalchemy import create_engine
from sqlalchemy.orm import (scoped_session, sessionmaker, synonym, relation, backref)
from sqlalchemy.ext.declarative import declarative_base, DeferredReflection
from zope.sqlalchemy import ZopeTransactionExtension


DBSession = scoped_session(sessionmaker(extension = ZopeTransactionExtension()))
Base = declarative_base(cls=DeferredReflection)


#Define your models here
class User(Base):
    __table__ = Table('users', Base.metadata, autoload = True)

我完全按照教程中对 Pyramid 的说明来做的(也就是在 init.py 中使用 Base.metadata.bind = engine),但我还是遇到了这个错误:

“sqlalchemy.exc.UnboundExecutionError: 这个表的 MetaData 没有绑定到任何引擎。请通过 autoload_with='someengine' 将引擎传递给表,或者通过 metadata.bind='someengine' 将 MetaData 与引擎关联。”

2 个回答

0

我已经通过下面的步骤解决了这个问题:

http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative.html#using-reflection-with-declarative

并且在我的init.py文件的主函数中添加了

Base.prepare(engine)

0

在你的引擎绑定之前,你不能使用 autoload。SQLA 在模块初始化时会尝试反射 users 表,尽管此时元数据还没有关联任何引擎。

我解决这个问题的方法有两个步骤 - 一个自定义的表工厂:

def AutoloadedTable(*args, **kwargs):
    rv = Table(*args, **kwargs)
    rv.deferred_autoloading = True
    return rv

这个工厂只是设置了 deferred_autoloading 属性,然后在引擎创建之后使用以下代码片段:

from sqlalchemy.engine import reflection

inspector = reflection.Inspector.from_engine(engine)
for i in list(metadata.tables.values()):
    if getattr(i, 'deferred_autoloading', False):
        inspector.reflecttable(i, None)

撰写回答