如何在SQLAlchemy中获取关系另一端的类型,而不创建对象?

4 投票
3 回答
1807 浏览
提问于 2025-04-16 04:39

如何获取与某个关系另一端的类名呢?这个类名在创建关系时就已经声明了。我猜这个信息应该在sqlalchemy.orm.util.class_mapper里。

假设我们有这三个类以及它们之间的关系: 一本书可以放在一个书架上(Book * --- 1 Shelf),并且一本书可以有多个作者(Book * --- * Author)。

class Shelf(Base):
    __tablename__ = 'shelves'
    id = Column(Integer, primary_key = True)
    name = Column(String)
    #one-to-many books by backref in Book.shelf

    def __init__(self, name=""):
        self.name = name

class Book(Base):
    __tablename__ = 'books'
    id = Column(Integer, primary_key = True)
    title = Column(String)
    #many-to-one shelf
    shelf_id = Column(Integer, ForeignKey('shelves.id'))
    shelf = relationship(Shelf, backref=backref('books', order_by=id))
    def __init__(self, title=""):
        self.title = title

author_book = Table('author_book', metadata, 
                    Column('author_id', Integer, ForeignKey('authors.id')),
                    Column('book_id', Integer, ForeignKey('books.id'))
                    )

class Author(Base):
    __tablename__ = 'authors'
    id = Column(Integer, primary_key = True)
    name = Column(String)
    #many-to-many books
    books = relationship('Book', secondary=author_book, backref='authors')

    def __init__(self, name=""):
        self.name = name

通过class_mapper(Class).iterate_properties,我们可以轻松获取不同的属性,比如ColumnProperty和RelationshipProperty。 应该有办法至少获取到与之相关的类的名称。有什么想法吗?

3 个回答

0

我找到了一种解决办法,但不太确定它是否总是有效。这个办法是用来查找在关系另一端期待的类(类型)。

class_mapper(Shelf)._props['books'].mapper.class_

我们可能不知道属性的名字(比如在这个例子中是 books),但其实没什么大不了的,可以通过字典 *_props* 来查找那些值,这些值是 sqlalchemy.orm.properties.RelationshipProperty 的实例。

2

从sqlalchemy 0.8版本开始,可以这样做:

from sqlalchemy import inspect
inspect(Shelf).relationships['books'].mapper.class_
3

也许有一个更简洁的解决方案。

for prop in class_mapper(Shelf).iterate_properties:
    if isinstance(prop, sqlalchemy.orm.RelationshipProperty):
       print prop.mapper.class_

这个方法可以在一对多和多对多的情况下,双向都能使用。

撰写回答