Project

Profile

Help

Story #3953

closed

ContentUnitSaver should support creating content with related models inside its transaction

Added by jortel@redhat.com about 6 years ago. Updated almost 5 years ago.

Status:
CLOSED - CURRENTRELEASE
Priority:
Normal
Assignee:
Category:
-
Sprint/Milestone:
Start date:
Due date:
% Done:

100%

Estimated time:
Platform Release:
Groomed:
Yes
Sprint Candidate:
No
Tags:
Sprint:
Sprint 42
Quarter:

Description

Problem

DeclarativeVersion (stages) currently supports creating content consisting of a single Content model. Many plugins such as RPM and Docker have complex content models. That is, each content (unit) is stored in multiple tables. The insert into these tables needs be committed atomically to prevent storing incomplete content. Further, the inserts need to happen in relational (referential) order and be compatible with bulk_create().

Solution

Add a hook to ContentUnitSaver that will pass the batch of DeclarativeVersion objects to a method called save_related(batch). The base implementation of this will do nothing, but subclasses can perform bulk_save calls there. The call to save_related occurs after the content units have been saved, but during the same transaction.


Related issues

Blocks RPM Support - Issue #3952: Using the ErrataRelatedModelSaver can result in creating incomplete content.CLOSED - CURRENTRELEASEbmbouterActions
Actions #1

Updated by daviddavis about 6 years ago

  • Blocks Issue #3952: Using the ErrataRelatedModelSaver can result in creating incomplete content. added
Actions #2

Updated by bmbouter about 6 years ago

  • Tracker changed from Task to Story
  • Description updated (diff)

Rewriting based on discussion w/ @jortel.

Actions #3

Updated by jortel@redhat.com about 6 years ago

The proposed solution of calling save_related() after the batch has been bulk created only supports one-to-many related models (with FK to Content).

Changing this to:

def _create_batch(batch)
    <move batch create code block here>

plugin writer would override as:

def _create_batch(batch):
     <create models where Content has FK to>
    super()._create_batch(batch)
    <create models with FK to Content>

This is step toward functional decomposition of the call and supports both one-to-many and many-to-one.

That said, having Content with FK to other models could introduce orphan clean up problems and can't think of a good use case for it. But, thinking the API should be as flexible as possible to avoid being short sighted.

In either case the new method should be protected (leading _).

Thoughts?

Actions #4

Updated by bmbouter about 6 years ago

I can't think of a specific situation, but I can imagine someone wanting to do some saving within the transaction prior to the content unit being saved. I think the hooks are simpler for this specific pattern. The hooks would be:

class CustomContentUnitSaver(ContentUnitSaver):

    def save_before(batch):
        """
        """

    def save_safter(batch):
        """
        """

I think the hooks are less hazard prone because they don't have to call super(). Also it encourages them to separate their before/after code into distinct functions.

What do you think?

Actions #5

Updated by jortel@redhat.com about 6 years ago

Calling super when overriding a method is common (recommended) practice and I'd be surprised if it posed a hazard. I prefer the approach I suggested mainly because it's a pattern I'm used to seeing. But, what you're proposing in #3953-4 will meet our needs as well.

Actions #6

Updated by bmbouter about 6 years ago

  • Subject changed from DeclarativeVersion should support creating content with related models. to ContentUnitSaver should support creating content with related models inside its transaction
  • Assignee set to bmbouter
  • Groomed changed from No to Yes
  • Sprint set to Sprint 42

OK sweet. I'm going to make this now so that we can resolve this Errata bug. I'll take that assigned also.

Grooming per the comment 5.

Actions #7

Updated by bmbouter about 6 years ago

  • Status changed from NEW to POST

Added by bmbouter about 6 years ago

Revision 1ce02a94 | View on GitHub

Add better support for related model saving

Adds pre_save() and post_save() handlers to ContentUnitSaver that plugin writers can override on subclasses.

https://pulp.plan.io/issues/3953 closes #3953

Added by bmbouter about 6 years ago

Revision 1ce02a94 | View on GitHub

Add better support for related model saving

Adds pre_save() and post_save() handlers to ContentUnitSaver that plugin writers can override on subclasses.

https://pulp.plan.io/issues/3953 closes #3953

Actions #8

Updated by bmbouter about 6 years ago

  • Status changed from POST to MODIFIED
  • % Done changed from 0 to 100
Actions #9

Updated by daviddavis over 5 years ago

  • Sprint/Milestone set to 3.0.0
Actions #10

Updated by bmbouter over 5 years ago

  • Tags deleted (Pulp 3)
Actions #11

Updated by bmbouter almost 5 years ago

  • Status changed from MODIFIED to CLOSED - CURRENTRELEASE

Also available in: Atom PDF