我有一个sqlalchemy模型,其中所有的表/对象都有一个notes字段。所以为了遵循干燥原则,我把场地搬到了一个混合班。在
class NotesMixin(object):
notes = sa.Column(sa.String(4000) , nullable=False, default='')
class Service(Base, NotesMixin):
__tablename__ = "service"
service_id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String(255), nullable=False, index=True, unique=True)
class Datacenter(Base, NotesMixin):
__tablename__ = "datacenter"
datacenter_id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String(255), nullable=False, index=True, unique=True)
class Network(Base, NotesMixin, StatusMixin):
__tablename__ = "network"
network_id = sa.Column(sa.Integer, primary_key=True)
etc...
现在notes列是model/db中的第一列。我知道这不会影响我的应用程序的功能,但是看到id前的注释会让我有点恼火,等等。有什么办法可以把它移到最后?在
找到了更干净的解决方案:
在sqlalchemy 0.6.5中使用
sqlalchemy.ext.declarative.declared_attr
修饰符(sqlalchemy.util.classproperty
在sqlalchemy<;=0.6.4中)根据文档,这是“对于具有外键的列,以及各种需要目标显式上下文的映射器级构造”。虽然严格说来不是这样,但它是通过在构造子类时调用方法(并创建列)来实现的,从而避免了复制的需要。这意味着mixin列将在最后出现。可能是比黑客攻击更好的解决方案。。。在
简单的答案是:只需自己创建数据库表,而不是让sqlalchemy用
metadata.create_all()
来完成。在如果您不认为这是可以接受的,恐怕这需要对
sqlalchemy.ext.declarative
本身做一个(小的)更改,或者您必须创建自己的元类并用metaclass
关键字参数将其传递给declarative_base()
。然后将使用该类代替默认的DeclarativeMeta
。在说明:sqlalchemy使用列属性的创建顺序,它将其存储在“private”属性
._creation_order
(在调用column()时生成)中。声明性扩展通过从mixin类创建column对象的副本并将其添加到类中来实现列的混合。此副本的._creation_order
设置为与mixin类的原始属性相同的值。由于mixin类当然是先创建的,所以它的列属性的创建顺序将低于子类。在因此,为了使您的请求成为可能,在制作副本时应该分配一个新的创建顺序,而不是使用原始的。您可以尝试根据这个解释创建自己的元类,并使用它。但您也可以尝试询问sqlalchemy开发人员。也许他们愿意将此作为bug/feature请求接受?至少,它看起来像是一个小的(一行)改变,除了你要求的改变(可以说是更好的)之外,不会有任何效果。在
相关问题 更多 >
编程相关推荐