【发布时间】:2017-08-20 08:55:01
【问题描述】:
我在我的新项目中使用 SQLAlchemy,并希望将 __slots__ 与模型一起使用(在没有炼金术的 beta 版本中,__slots__ 是必需的,因为创建了大量对象)。但我无法将它们与 SQLAlchemy 声明结合起来,并得到以下代码错误:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class NotWorking(Base):
__tablename__ = 'table1'
pk = Column(Integer, primary_key=True)
name = Text(length=64, convert_unicode=True)
__slots__ = ['name', 'pk']
错误
ValueError: 'name' in __slots__ conflicts with class variable
这应该是__slots__ 修改类来为其中定义的字段创建描述符,因此一种解决方法是使隐藏字段 (_name) 并使模型字段充当属性,如下所示:
class Working(Base):
__tablename__ = 'table2'
pk = Column(Integer, primary_key=True)
name = Text(length=64, convert_unicode=True)
__slots__ = ['_name', '_pk']
# Workaround
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
但是这段代码编写起来可能有点乏味,您需要为每个新字段添加相应的属性。我想知道,有没有更好的方法可以不用属性,同时仍然使用声明性基础(不使用经典映射)。
【问题讨论】:
-
语句
name = Text(length=64, convert_unicode=True)不是已经创建了正确的描述符吗?所以你有__slots__ = ()表示没有额外的实例变量需要存储? -
__slots__旨在减少内存消耗,并且可能使对象更加静态,但是(我发现在检查您的评论后)因为 Base 没有定义它们,它们并不完全有用.__dict__仍然存在,您仍然可以添加新字段,因此它们最多只能用作指导。
标签: python sqlalchemy slots