2017-07-25 56 views
0

我正在使用sqlalchemy的ORM創建映射到SQL表的類。我遇到了在這些類之間產生關係的問題,因爲它們在聲明類之前互相引用。當我運行代碼解釋器投訴NameError: name 'Account' is not definedPython - 類在引用前引用另一個類

我已經在下面包含了一個代碼示例,演示了我如何聲明這些類。

class Location(Base): 
    __tablename__ = 'locations' 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    address = Column(String) 
    city = Column(String) 
    state = Column(String) 
    zip_code = Column(String) 

    account = sa.orm.relationship('Account', order_by=Account.id, back_populates='location') 
    entity = sa.orm.relationship('Entity', order_by=Entity.id, back_populates='location') 

    def __repr__(self): 
     return "<Location(name='{}', address='{}', city='{}', state='{}', zip_code='{}')>".\ 
        format(self.name, self.address, self.city, self.state, self.zip_code) 


class Account(Base): 
    __tablename__ = 'accounts' 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    number = Column(String) 
    institution = Column(String) 
    # entity_id = Column(Integer, sa.ForeignKey('entities.id')) 

    entity = sa.orm.relationship('Entity', back_populates='accounts') 
    location = sa.orm.relationship('Location', order_by=Location.id, back_populates='account') 

    def __repr__(self): 
     return "<Account(name='{}', account={}, institution={}, entity={})>".\ 
       format(self.name, self.number, self.institution, self.entity) 


class Entity(Base): 
    __tablename__ = 'entities' 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 

    accounts = sa.orm.relationship('Account', order_by=Account.id, back_populates='entity') 
    location = sa.orm.relationship('Location', order_by=Location.id, back_populates='entity') 

    def __repr__(self): 
     return "<Entity(name='{}', location='{}')>".format(self.name, self.location) 

我在這裏錯過了什麼?有沒有辦法定義所有的類,然後儘可能地用函數調用它們?例如與功能,它所有的功能後,在底部打電話主要是簡單的定義:

def main(): 
    foo() 

def foo(): 

if __name__=='__main__': 
    main() 

回答

0

定義你排序無論是作爲可調用或表達的字符串,如relationship API documentation解釋說:

class Location(Base): 
    ... 
    account = sa.orm.relationship('Account', 
     order_by=lambda: Account.id, ...) 

class Location(Base): 
    ... 
    account = sa.orm.relationship('Account', 
     order_by='Account.id', ...) 

的問題是,位置類主體的評估過程中帳戶的名稱還沒有在全球範圍內的存在,而不是在本體範圍內定義。在函數/λ傳遞允許推遲評估爲「映射器初始化時間」:

通過relationship()接受一些參數任選地接受一個可調用的函數,該函數調用時產生所期望的值。在「映射器初始化」時間,父代Mapper調用可調用的調用,該調用僅在第一次使用映射器時發生,並假定在所有映射構建完成後。這可以用來解決訂單的聲明和其他依賴問題,比如如果Child是在同一個文件

將字符串傳遞聲明如下Parent也將解決訂單的申報問題,並提供另一個功能:

這些字符串參數被轉換爲可以將字符串評估爲Python代碼的可調用函數,使用Declarative類註冊表作爲名稱空間。這允許通過其字符串名稱自動查找相關類,並且不需要將相關類根本導入到本地模塊空間

+0

謝謝!在發佈這個問題後,我意識到這個問題可能與orm關係中的order_by參數有關,但我沒有意識到還有另一種方法來定義這些問題以避免此問題。 – Evan