Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.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 “炼金术”;包含“你渴望”;似乎不加载嵌套关系_Python_Python 2.7_Sqlalchemy_Eager Loading - Fatal编程技术网

Python “炼金术”;包含“你渴望”;似乎不加载嵌套关系

Python “炼金术”;包含“你渴望”;似乎不加载嵌套关系,python,python-2.7,sqlalchemy,eager-loading,Python,Python 2.7,Sqlalchemy,Eager Loading,我有一个模式如下: Thing # Base class for below tables - id Ball (Thing) - color Bin (Thing) - ball -> Ball.id Court (Thing) - homeBin -> Bin.id - awayBin -> Bin.id 我想确保,每当我加载一组球场s时,它都包含最新的Ball列值。据我所知,我可能能够帮助: 指示应该从查询中手动指定的列中急切地加载给定属性 我有一个测试,每隔几秒

我有一个模式如下:

Thing # Base class for below tables
- id

Ball (Thing)
- color

Bin (Thing)
- ball -> Ball.id

Court (Thing)
- homeBin -> Bin.id
- awayBin -> Bin.id
我想确保,每当我加载一组
球场
s时,它都包含最新的
Ball
列值。据我所知,我可能能够帮助:

指示应该从查询中手动指定的列中急切地加载给定属性

我有一个测试,每隔几秒钟查询一次任何
球场
s。我发现,即使使用
contains\u eager
,我也只能看到
Ball
.color的相同值,即使我已经在数据库中显式更新了列的值

为什么sqlalchemy似乎重用了这些旧数据

下面是正在发生的工作示例:

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

Base = declarative_base()

class Thing(Base):
    __tablename__ = "Things"
    id = Column(Integer, primary_key=True)
    name = Column(String(256))
    thingType = Column(String(256))
    __mapper_args__ = {
            'with_polymorphic':'*',
            'polymorphic_on':"thingType",
            'polymorphic_identity':"thing"
        }


class Ball(Thing):
    __tablename__ = "Balls"
    id = Column('id', Integer, ForeignKey('Things.id'), primary_key=True)
    color = Column('color', String(256))
    __mapper_args__ = {
        'polymorphic_identity':'ball'
    }

class Bin(Thing):
    __tablename__ = "Bins"
    id = Column('id', Integer, ForeignKey('Things.id'), primary_key=True)
    shape = Column('shape', String(256))
    ballId = Column('ballId', Integer, ForeignKey('Balls.id'))
    ball = relationship(Ball, foreign_keys=[ballId], backref="outputBins")
    __mapper_args__ = {
        'polymorphic_identity':'bin'
    }
    pass

class Court(Thing):
    __tablename__ = "Courts"
    id = Column('id', Integer, ForeignKey('Things.id'), primary_key=True)
    homeBinId = Column('homeBinId', Integer, ForeignKey('Bins.id'))
    awayBinId = Column('awayBinId', Integer, ForeignKey('Bins.id'))
    homeBin = relationship(Bin, foreign_keys=[homeBinId], backref="homeCourts")
    awayBin = relationship(Bin, foreign_keys=[awayBinId], backref="awayCourts")
    __mapper_args__ = {
        'polymorphic_identity':'court'
    }

metadata = MetaData()
engine = create_engine("postgresql://localhost:5432/")
Session = sessionmaker(bind=engine)
session = Session()

def courtQuery():
    awayBalls = aliased(Ball, name="awayBalls")
    homeBalls = aliased(Ball, name="homeBalls")
    awayBins = aliased(Bin, name="awayBins")
    homeBins = aliased(Bin, name="homeBins")

    query = session.query(Court)\
        .outerjoin(awayBins, Court.awayBinId == awayBins.id)\
        .outerjoin(awayBalls, awayBins.ballId == awayBalls.id)\
        .outerjoin(homeBins, Court.homeBinId == homeBins.id)\
        .outerjoin(homeBalls, homeBins.ballId == homeBalls.id)\
        .options(contains_eager(Court.awayBin, alias=awayBins).contains_eager(awayBins.ball, alias=awayBalls))\
        .options(contains_eager(Court.homeBin, alias=homeBins).contains_eager(homeBins.ball, alias=homeBalls))
    return [r for r in query]

import time

while(True):
    results = courtQuery()
    court = results[0]
    ball = court.homeBin.ball
    print(ball.color) # does not change
    time.sleep(2)
环境:

  • Python 2.7.14
  • SqlAlchemy 1.3.0b1
  • 博士后11.3(尽管我已经看到了这一点 (在Oracle上也是如此)

您处理会话和事务生存期的方式似乎存在问题。通常情况下,在帖子本身中包含这些内容也会更好。@IljaEveriläAh有趣。我认为上面的代码是问题所在,所以我没有想过要考虑这个问题。我如何以不同的方式处理会话?我还将更新代码,以更全面地表示正在发生的事情。我并不是说这是肯定的,但通常当更新似乎没有被读取时,就是没有及时提交/回滚和/或关闭会话。SQLAlchemy在事务隔离的特定假设下运行,因此,如果您以前从DB读取过会话中的某个对象,那么当它再次看到同一行的id时,它不会更新其状态。医生比我解释得更清楚,包括边缘案件等。看来这次治疗可能是罪魁祸首。在执行查询之前插入“session.expire_all()”可确保提取新数据。我想我只是不确定contains_eager是如何工作的,如果它确实急切地获取最新的数据,但实际上没有更新对象。这看起来像是您处理会话和事务生存期的方式的问题。通常情况下,在帖子本身中包含这些内容也会更好。@IljaEveriläAh有趣。我认为上面的代码是问题所在,所以我没有想过要考虑这个问题。我如何以不同的方式处理会话?我还将更新代码,以更全面地表示正在发生的事情。我并不是说这是肯定的,但通常当更新似乎没有被读取时,就是没有及时提交/回滚和/或关闭会话。SQLAlchemy在事务隔离的特定假设下运行,因此,如果您以前从DB读取过会话中的某个对象,那么当它再次看到同一行的id时,它不会更新其状态。医生比我解释得更清楚,包括边缘案件等。看来这次治疗可能是罪魁祸首。在执行查询之前插入“session.expire_all()”可确保提取新数据。我想我只是不确定contains_eager是如何工作的,如果它确实急切地获取最新的数据,但实际上没有更新对象。