flask-sqlachemy: 无法使父项侦听并更新子项的更改

2024-06-17 09:25:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我要通过一个测试:

@pytest.fixture(scope='function')
@pytest.mark.usefixtures('db')
def new_scan_service(db):
    user = User.create(username='Princess Leia', email='dontatme@me.com')
    date = datetime.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')
    experiment1 = Experiment.create(date=date, scanner='GE', num_scans=2, user_id=user.id)
    experiment2 = Experiment.create(date=date, scanner='GE', num_scans=2, user_id=user.id)
    db.session.commit()
    print('I just put the user and two experiments into the database', user.num_experiments)
    s = ScanService(user.id, experiment2.id)
    return s

class TestScanUpload:

    def test_xnat_ids_correctly_generated_for_multiple_experiments_and_scans(self, new_scan_service):
        """
        Given a subject with more than one experiment, and an experiment with more than one scan
        When xnat ids are generated
        Then test that xnat_experiment_id and xnat_scan_id are as expected
        """

        with open('<file-path>', 'r') as f:
            xnat_ids = new_scan_service._generate_xnat_identifiers()
            assert xnat_ids['experiment']['xnat_id'] == '000001_MR2'

user.num_experiments每次我得到一个新的实验时应该增加一个。我在Stack Overflow的某个地方读到,这比每次你想知道一个用户有多少个实验时都要做一个查询要快。你知道吗

我试图使用sqlachemy.event来监听实验的创建并更新user.num_experiments。你知道吗

我试过一件事。我将此代码放在定义实验模型的模块中:

def update_user_exp_count(mapper, connection, target):
    db.session.begin_nested()
    user_id = target.user_id
    print("user id is ", user_id)
    user = User.get_by_id(user_id)
    user.num_experiments += 1
    print("This is my listener.  user.num experiments is", user.num_experiments)
    db.session.add(user)
    db.session.commit()

event.listen(Experiment, 'before_insert', update_user_exp_count)

测试失败并出现断言错误,下面是我的标准输出:

user id is  1
This is my listener.  user.num experiments is 1
user id is  1
This is my listener.  user.num experiments is 1
I just put the user and two experiments into the database. user.num_experiments is  0

所以调用了我的侦听器,但数据库表中的用户对象从未以持久方式更新。你知道吗

我还尝试了遵循this question中的示例。你知道吗

下面是用户模型的相关部分。你知道吗

class User(UserMixin, SurrogatePK, Model):
    """A user of the app."""

    __tablename__ = 'users'
    username = Column(db.String(80), unique=True, nullable=False)
    email = Column(db.String(80), unique=True, nullable=False)
    num_experiments = Column(db.Integer(), default=0)
    experiments = relationship('Experiment', backref='user', lazy='dynamic')

实验模型的(reference_col是cookiecutter烧瓶中定义的插入外键的函数):

class Experiment(SurrogatePK, Model):
    """A user's experiment, during which they are scanned."""

__tablename__ = 'experiments'
date = Column(db.Date(), nullable=False)
scanner = Column(db.String(80), nullable=True)
num_scans = Column(db.Integer(), nullable=True)
user_id = reference_col('users', nullable=True)

我将此代码放在定义用户模型的模块中:

  @event.listens_for(User.experiments, 'append')
    def receive_append(target, value, initiator):
        print("I was executed")
        target.num_experiments += 1

这永远不会被执行。你知道吗

我该怎么做才能让父母倾听新的孩子,并在得到他们时更新自己?我很感激你能提供的任何帮助。你知道吗

更新:我已经开发了一种方法来解决这个问题。但我还是很想知道为什么我不能使用听众。以下是我的解决方法:

class ExperimentService:

    def add(self, user, date, scanner, num_scans):
        exp = Experiment.create(date=date, scanner=scanner, num_scans=num_scans, user_id=user.id)
        user.update(num_experiments=user.num_experiments + 1)
        print("here I am in the add function. user.num_experiments is ", user.num_experiments)
        return exp

.update是cookiecutter烧瓶提供的方便方法之一。当我这么做的时候,我的测试通过了。所以我剩下的问题是:

为什么即使执行了update_user_exp_count,更改似乎也不会持久存在于数据库中?你知道吗

以及

为什么receive_append从未执行过?你知道吗


Tags: theiddbdateisdefcolumnnum