Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQLAlchemy,即时加载postgresql INET/CIDR关系_Python_Postgresql_Sqlalchemy - Fatal编程技术网

Python SQLAlchemy,即时加载postgresql INET/CIDR关系

Python SQLAlchemy,即时加载postgresql INET/CIDR关系,python,postgresql,sqlalchemy,Python,Postgresql,Sqlalchemy,我在postgresql中有两个表,一个名为ip_address,另一个名为network ip_地址表有两列: id是一个整数 v4address是一个INET 网络表有两列: id是一个整数 这是一个CIDR 我希望能够选择ip_地址并急切地加载ip_地址网络,而不必在表之间定义基于id的外键关系。id列由其他与其他表无关的关系使用 实现这一点的SQL是: select * from ip_address join network on ip_address.v4address <&l

我在postgresql中有两个表,一个名为ip_address,另一个名为network

ip_地址表有两列:

id是一个整数 v4address是一个INET 网络表有两列:

id是一个整数 这是一个CIDR 我希望能够选择ip_地址并急切地加载ip_地址网络,而不必在表之间定义基于id的外键关系。id列由其他与其他表无关的关系使用

实现这一点的SQL是:

select * from ip_address join network on ip_address.v4address << network.v4representation;
这是可行的,但当我实际尝试在应用程序中使用此属性时,我会遇到典型的N+1查询问题。我想用这样一种方式来定义它,以便能够在网络中急切地加载ip地址

我曾尝试使用primaryjoin将其定义为一种关系,但不知道需要什么。我试过这个:

networks = db.relationship("Network",
                           primaryjoin='IPAddress.v4address << Network.v4representation',
                           viewonly=True)
我尝试了几种为关系定义外键的组合:

但是sqlalchemy抛出了错误: ArgumentError:关系IPAddress.networks无法根据连接条件和远程参数确定任何明确的本地/远程列对。考虑使用远程注释来准确地标记关系的远程侧的连接条件的元素。

将IPAddress.v4address或Network.v4representation指定为远程\u端都不会更改异常

用foreign/remote注释primaryjoin条件的尝试也没有帮助

回到我最初的意图,我希望能够执行一个查询,该查询将返回ip地址并立即加载他们的网络以及可能来自网络和其他关系的数据,因为这是我的完整模式的简化

有人有什么建议吗


提前感谢。

这里缺少的一点是,自定义操作符没有在关系框架内工作。为了在这种情况下提供帮助,我为SQLAlchemy 0.9.2添加了一个新特性,它是is_比较标志,下面是一个示例,位于

以下是一个使用较少的公共API实现相同结果的版本,该版本也适用于0.8:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.dialects.postgresql import INET, CIDR

Base = declarative_base()

# workaround before 0.9.2
from sqlalchemy.sql import operators
is_contained_by = operators.custom_op("<<")
operators._comparison.add(is_contained_by)

class IPA(Base):
    __tablename__ = 'ip_address'

    id = Column(Integer, primary_key=True)
    v4address = Column(INET)

    network = relationship("Network",
                        primaryjoin=lambda: is_contained_by(
                                     IPA.v4address, 
                                     (foreign(Network.v4representation))
                                    ),
                        viewonly=True
                    )
class Network(Base):
    __tablename__ = 'network'

    id = Column(Integer, primary_key=True)
    v4representation = Column(CIDR)

print Session().query(IPA).join(IPA.network)
在0.9.2及更高版本中,可按以下方式进行:

class IPA(Base):
    __tablename__ = 'ip_address'

    id = Column(Integer, primary_key=True)
    v4address = Column(INET)

    network = relationship("Network",
                        primaryjoin="IPA.v4address.op('<<', is_comparison=True)"
                            "(foreign(Network.v4representation))",
                        viewonly=True
                    )
ArgumentError: Could not locate any relevant foreign key columns for primary join condition 'public.ip_address.v4address << public.network.v4representation' on relationship IPAddress.networks.  Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or are annotated in the join condition with the foreign() annotation.
networks = db.relationship("Network",
                           primaryjoin='IPAddress.v4address.op("<<")(Network.v4representation)',
                           foreign_keys='[Network.v4representation]',
                           viewonly=True)
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.dialects.postgresql import INET, CIDR

Base = declarative_base()

# workaround before 0.9.2
from sqlalchemy.sql import operators
is_contained_by = operators.custom_op("<<")
operators._comparison.add(is_contained_by)

class IPA(Base):
    __tablename__ = 'ip_address'

    id = Column(Integer, primary_key=True)
    v4address = Column(INET)

    network = relationship("Network",
                        primaryjoin=lambda: is_contained_by(
                                     IPA.v4address, 
                                     (foreign(Network.v4representation))
                                    ),
                        viewonly=True
                    )
class Network(Base):
    __tablename__ = 'network'

    id = Column(Integer, primary_key=True)
    v4representation = Column(CIDR)

print Session().query(IPA).join(IPA.network)
class IPA(Base):
    __tablename__ = 'ip_address'

    id = Column(Integer, primary_key=True)
    v4address = Column(INET)

    network = relationship("Network",
                        primaryjoin="IPA.v4address.op('<<', is_comparison=True)"
                            "(foreign(Network.v4representation))",
                        viewonly=True
                    )