如何使用SQLAlchemy声明式ORM在声明的属性上设置索引?

时间:2018-10-16 11:02:34

标签: python sqlalchemy

当我尝试在声明的属性上定义索引

class Event(Base):

    @declared_attr
    def user_id(cls):
        return Column(BigInteger, ForeignKey("users.user_id"), nullable=False)

    idx_event_user_id = Index('idx_event_user_id', user_id)

我收到以下错误:

sqlalchemy.exc.ArgumentError: Element <sqlalchemy.ext.declarative.api.declared_attr object at 0x1066ec648> is not a string name or column element

还有另一种方法吗?我可以在声明的属性上设置索引吗?

1 个答案:

答案 0 :(得分:0)

在处理继承/混合时,应使用class Event(Base): @declared_attr def user_id(cls): return Column(BigInteger, ForeignKey("users.user_id"), nullable=False) @declared_attr def __table_args__(cls): # Return a tuple of arguments to pass to Table return (Index(f'idx_{cls.__tablename__}_user_id', 'user_id'),) 将要为所有类及其基础Table创建的索引传递为“内联”定义,该索引也应在其中声明为属性如"Creating Indexes with Mixins"中所述:

cls.foo_id

这将避免为不同(子)类创建的索引之间的名称冲突。请注意,这里的“内联”格式使用字符串名称来标识要索引的列,但是class Event(Base): @declared_attr def user_id(cls): return Column(BigInteger, ForeignKey("users.user_id"), nullable=False, index=True) 在声明的属性中也可以使用。通常,无需将Index分配为模型属性,在某些情况下无需分配it may even lead to confusion

为列建立索引的简单解决方案是将index=True传递给Column。这是为相关列创建匿名索引的快捷方式:

@declared_attr

当您不处理继承/混合时,不需要class MyModel(Base): foo = Column(Integer) bar = Column(Integer) # "Inline", but gets the actual column instead of a string name. # Possible with Declarative. __table_args__ = (Index('idx_mymodel_foo', foo),) # Finds the table through the Column used in the definition. Index('idx_mymodel_bar', MyModel.bar) 包装:

idx_event_user_id = Index('idx_event_user_id', user_id)

出现错误的原因是,在类构造期间,将评估类定义的主体,然后将所得的名称空间用作类的名称空间。在评估期间

Index

导致user_id照原样接收在该命名空间中分配给#include <iostream> #include <deque> #include <vector> int main() { std::vector< std::deque<int> > vector_of_deques; vector_of_deques.push_back( std::deque<int>{1, 2, 3, 4, 5} ); std::deque<int> deque = *(vector_of_deques.begin()); int split_position; if (deque.size() % 2 == 0) split_position = deque.size() / 2; else split_position = int(deque.size() / 2) + 1; vector_of_deques.emplace_back( deque.begin() + split_position, deque.end() ); deque.erase( deque.begin() + split_position, deque.end() ); for (auto i: vector_of_deques) { for (auto j: i) std::cout << j << ", "; std::cout << std::endl; } return 0; } 的声明属性descriptor对象,因此SQLAlchemy抱怨。

当您通过构造的类对象或其实例访问描述符时,它们开始做自己的事情,这在declared attribute的情况下意味着它求值为映射的属性或它代表的特殊声明性成员