在没有检测的情况下在SQLAlchemy中实例化声明性类

时间:2016-07-07 18:38:41

标签: python sqlalchemy

我正在开发一个使用sqlalchemy来提取大量数据的应用程序。应用程序对结果对象进行了大量计算,但从不对这些对象进行任何更改。应用程序太慢,并且分析表明花费大量时间来访问由sqlalchemy管理的属性。因此,我试图找出如何防止sqlalchemy检测这些对象。

到目前为止,我已基于this answerthis example取得了一些进展。我发现了两种不同的方法,但似乎没有一种方法可以用于人际关系。我大部分都是在没有全面了解sqlalchemy的内部结构的情况下进行的。在这两种情况下,我都使用以下测试会话和数据:

engine = create_engine('sqlite://')
engine.execute('CREATE TABLE foo (id INTEGER, name TEXT)')
engine.execute('INSERT INTO foo VALUES (0, \'Jeremy\')')
engine.execute('CREATE TABLE bar (id INTEGER, foo_id Integer)')
engine.execute('INSERT INTO bar VALUES (0, 0)')
engine.execute('INSERT INTO bar VALUES (1, 0)')
Session = sessionmaker(bind=engine)
session = Session()

然后我要么(1)使用InstrumentationManager的自定义子类:

class ReadOnlyInstrumentationManager(InstrumentationManager):
    def install_descriptor(self, class_, key, inst):
        pass

Base = declarative_base()
Base.__sa_instrumentation_manager__ = ReadOnlyInstrumentationManager

class Bar(Base):
    __tablename__ = 'bar'
    id = Column(Integer, primary_key=True)
    foo_id = Column(Integer, ForeignKey('foo.id'))

class Foo(Base):
    __tablename__ = 'foo'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    bars = relationship(Bar)

f = session.query(Foo).first()
print type(f.bars)

给出:

<class 'sqlalchemy.orm.relationships.RelationshipProperty'>

而不是预期的酒吧列表。

或者,(2)使用ClassManager的自定义子类:

class MyClassManager(ClassManager):
    def new_instance(self, state=None):
        if hasattr(self.class_, '__readonly_type__'):
            instance = self.class_.__readonly_type__.__new__(self.class_.__readonly_type__)
        else:
            instance = self.class_.__new__(self.class_)
        self.setup_instance(instance, state)
        return instance

Base = declarative_base()
Base.__sa_instrumentation_manager__ = MyClassManager

class ReadonlyFoo(object):
    pass

class ReadonlyBar(object):
    pass

class Bar(Base, ReadonlyBar):
    __tablename__ = 'bar'
    __readonly_type__ = ReadonlyBar
    id = Column(Integer, primary_key=True)
    foo_id = Column(Integer, ForeignKey('foo.id'))

class Foo(Base, ReadonlyFoo):
    __tablename__ = 'foo'
    __readonly_type__ = ReadonlyFoo
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    bars = relationship(Bar)

f = session.query(Foo).first()
print f.bars

给出:

AttributeError: 'ReadonlyFoo' object has no attribute 'bars'

有没有办法修改其中一种方法,以便关系仍然有效?或者,这个问题的另一种方法是否更好?

0 个答案:

没有答案