SQLAlchemy的声明和延迟列加载

6 投票
2 回答
2351 浏览
提问于 2025-04-15 19:26

在SQLAlchemy中,是否可以指定某些列为延迟加载?我正在使用sqlalchemy.ext.declarative模块来定义我的映射,举个例子:

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class SomeClass(Base):
    __tablename__ = 'some_table'
    id = Column(Integer, primary_key=True)
    name =  Column(String(50))

我想让比如说“name”这一列使用延迟加载,我该怎么做呢?

谢谢你,
Jan

2 个回答

2

不要为你想要按需加载的列定义映射。然后按照延迟列加载的说明,使用mapper对象进行配置。修改后的代码如下:

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class SomeClass(Base):
    __tablename__ = 'some_table'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    #big_name = Column(String(500))

SomeClass.__table__.append_column(Column('big_name', String(500)))
SomeClass.__mapper__.add_property('big_name', deferred(SomeClass.__table__.c.big_name))

运行这段测试代码:

c = session.query(SomeClass).first()
# here SQL is loading all configured properties, but big_name
print "c: ", c
# only here another SQL request is made to load the property
print "big_name: ", c.big_name

会产生以下日志摘录:

... INFO sqlalchemy.engine.base.Engine.0x...77d0 SELECT some_table.id AS some_table_id, some_table.name AS some_table_name 
FROM some_table 
LIMIT 1 OFFSET 0

... INFO sqlalchemy.engine.base.Engine.0x...77d0 SELECT some_table.big_name AS some_table_big_name 
FROM some_table 
WHERE some_table.id = ?
12

只需要在列的声明周围加上 deferred() 就可以了:

class SomeClass(Base):
    __tablename__ = 'some_table'
    id = Column(Integer, primary_key=True)
    name =  deferred(Column(String(50)))

撰写回答