我正在尝试创建一个具有连接之间的关系。以下是我正在尝试做的一个简短示例:
#!/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 ?
这个问题的答案是肯定的,但我无法弄清楚如何告诉它
答案 0 :(得分: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]
)