Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add content related story models and services #16

Merged
merged 1 commit into from
Jun 5, 2021
Merged

Conversation

gaoxk
Copy link
Contributor

@gaoxk gaoxk commented Jun 3, 2021

Notion ticket link

Build stories and related models

Implementation description

  • add models for stories, story content, and their translations
  • see architecture doc

New API

mutation {
  createStory(storyData: {stage: START, description: "heres my story", youtubeLink: "no!", level: 1, translatedLanguages: []}) {
    story {
      id
    }
  }
}

{
  storyById(id:1){
    youtubeLink
    translatedLanguages
  }
}
{
  stories {
    youtubeLink
  }
}

Tentative Queries

Column index decisions were made based on these queries. Each query uses the indexes to some degree.

// Load Homepage
// Show all stories I am translating or reviewing 
SELECT * FROM stories INNER JOIN story_translations ON stories.id = story_translations.id WHERE story_translations.translator_id = ? OR story_translations.reviewer_id = ?;
// Show all stories available for translation or reviewing to me
SELECT * FROM stories WHERE NOT (translated_languages @> ARRAY['mylanguage']::varchar[]);

// Load Translation Platform
SELECT * FROM story_contents WHERE story_id = ?;
SELECT * FROM story_translations INNER JOIN story_translation_contents ON story_translations.id = story_translation_contents.id  WHERE story_translations.id = ?;

// Save Translation
UPDATE story_translation_contents SET translation_content = ? WHERE story_translation_id = ? AND line_index = ?;

Note about showing available stories

translated_languages could've been a json dictionary for looking up if a language was translated or not. I tried testing the query in both conditions and there's a marginal improvement with the array. I predict the array will still perform better, but this is not too challenging to change in the future.

planet-read=# EXPLAIN SELECT * FROM stories WHERE NOT (translated_languages @> ARRAY['hi']::varchar[]);
                              QUERY PLAN
-----------------------------------------------------------------------
 Seq Scan on stories  (cost=0.00..17.50 rows=597 width=108)
   Filter: (NOT (translated_languages @> '{hi}'::character varying[]))
(2 rows)


planet-read=# EXPLAIN SELECT * FROM stories WHERE translated_languages->>'field' = 'hi';
                            QUERY PLAN
-------------------------------------------------------------------
 Seq Scan on stories  (cost=0.00..19.00 rows=3 width=108)
   Filter: ((translated_languages ->> 'field'::text) = 'hi'::text)
(2 rows)

Caution

  • stories.translatedLanguages could technically fall out of sync from what is actually translated. We will need to keep it in sync with story_translations via api

Checklist

  • My PR name is descriptive and in imperative tense
  • My commit messages are descriptive and in imperative tense. My commits are atomic and trivial commits are squashed or fixup'd into non-trivial commits
  • For backend changes, I have run the appropriate linters: docker exec -it <backend-container-id> /bin/bash -c "black . && isort --profile black ."
  • I have requested a review from the PL, as well as other devs who have background knowledge on this PR or who will be building on top of this PR

@gaoxk gaoxk marked this pull request as ready for review June 4, 2021 04:10
Copy link
Collaborator

@e-wai e-wai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me? Added a couple questions

@@ -1,13 +1,16 @@
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
erase_db_and_sync = False
erase_db_and_sync = True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we want this to default to True vs. toggling to clear as necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah crap, my bad. good catch

translated_languages = db.Column(db.ARRAY(db.String))
contents = db.relationship(StoryContent)

def to_dict(self, include_relationships=False):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an example of what this result looks like? Like even just to be added within this comment thread for reference

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very much what you might expect:

{
 "id": 1,
 "stage": START,
....
}

The funky to_dict is from starter-code. you could probably get away with just object.__dict__ for most things, but this fn will come in handy for including relationships too.

pass

@abstractmethod
def create_story(self, story):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there use cases for the remaining CRUD operations (bulk or individual)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - getting all stories will be a good spring board into the specific filters and conditions down the road. It's also good for mvp testing on the frontend side.

get_story by id will be needed for loading up the translation platform once a story is selected.

@gaoxk
Copy link
Contributor Author

gaoxk commented Jun 5, 2021

TFTR (thanks for the review)!! 🚢

@gaoxk gaoxk merged commit fcc0f53 into main Jun 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants