2010-04-13 39 views
1

我試圖創建一個加入之間有關係。這裏是我想要做一個比較短的例子:sqlalchemy orm關係加入之間的問題

#!/usr/bin/env python 
import sqlalchemy as sa 
from sqlalchemy import orm 
from sqlalchemy.ext.declarative import declarative_base 


metadata = sa.MetaData() 
Base = declarative_base(metadata=metadata) 

engine = sa.create_engine('sqlite:///:memory:') 

class Network(Base): 
    __tablename__ = "network" 
    id = sa.Column(sa.Integer, primary_key=True) 
    ip_net_addr_db = sa.Column('ip_net_addr', sa.Integer, index=True) 
    ip_broadcast_addr_db = sa.Column('ip_broadcast_addr', sa.Integer, index=True) 
    # This can be determined from the net address and the net mask, but we store 
    # it in the db so that we can join with the address table. 
    ip_net_mask_len = sa.Column(sa.SmallInteger) 

class Address(Base): 
    __tablename__ = "address" 
    ip_addr_db = sa.Column('ip_addr', sa.Integer, primary_key=True, 
       index=True, unique=True) 

Network.addresses = orm.relation(Address, 
    primaryjoin=Address.ip_addr_db.between(
       Network.ip_net_addr_db, 
       Network.ip_broadcast_addr_db), 
    foreign_keys=[Address.ip_addr_db])  

metadata.create_all(engine) 

Session = orm.sessionmaker(bind=engine) 

Network() 

如果你運行它,你會得到這樣的錯誤:

ArgumentError: Could not determine relation direction for primaryjoin condition 
'address.ip_addr BETWEEN network.ip_net_addr AND network.ip_broadcast_addr', on relation Network.addresses. 
Do the columns in 'foreign_keys' represent only the 'foreign' columns in this join condition ? 

的問題的答案是肯定的,但我不能弄清楚如何告訴它:

回答

2

SQLAlchemy遍歷條件以在其中查找本地 - 遠程對來確定關係的列和基數。該算法僅適用於二元運算符。解決你的情況的簡單方法是用兩個操作員重寫BETWEEN。而不是,他們是不是「平等」的運營商,所以你不能用這種關係來追加新的地址,這就是爲什麼使用viewonly=True

Network.addresses = orm.relation(Address, 
    viewonly=True, 
    primaryjoin=(
     (Address.ip_addr_db>=Network.ip_net_addr_db) & 
     (Address.ip_addr_db<=Network.ip_broadcast_addr_db) 
    ), 
    foreign_keys=[Address.ip_addr_db] 
) 
+0

感謝。這很棒。 – 2010-04-13 10:38:02