Skip to content

Commit

Permalink
Update timestamps at DB level
Browse files Browse the repository at this point in the history
  • Loading branch information
leplatrem committed Jul 6, 2023
1 parent 3bb72bf commit 7f33937
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 36 deletions.
18 changes: 7 additions & 11 deletions ctms/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, TypeVar, cast

from pydantic import UUID4
from sqlalchemy import asc, or_
from sqlalchemy import asc, or_, text
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.orm import Session, joinedload, load_only, selectinload

Expand Down Expand Up @@ -52,8 +52,6 @@
UpdatedAddOnsInSchema,
UpdatedEmailPutSchema,
UpdatedFirefoxAccountsInSchema,
UpdatedNewsletterInSchema,
UpdatedWaitlistInSchema,
WaitlistInSchema,
)
from .schemas.base import BaseModel
Expand Down Expand Up @@ -463,12 +461,12 @@ def create_or_update_newsletters(
) # This doesn't need to be synchronized because the next query only alters the other remaining rows. They can happen in whatever order. If you plan to change what the rest of this function does, consider changing this as well!

if newsletters:
newsletters = [UpdatedNewsletterInSchema(**news.dict()) for news in newsletters]
stmt = insert(Newsletter).values(
[{"email_id": email_id, **n.dict()} for n in newsletters]
)
stmt = stmt.on_conflict_do_update(
constraint="uix_email_name", set_=dict(stmt.excluded)
constraint="uix_email_name",
set_={**dict(stmt.excluded), "update_timestamp": text("NOW()")},
)

db.execute(stmt)
Expand All @@ -487,15 +485,13 @@ def create_waitlist(
def create_or_update_waitlists(
db: Session, email_id: UUID4, waitlists: List[WaitlistInSchema]
):
waitlists_to_upsert = [
UpdatedWaitlistInSchema(**waitlist.dict()) for waitlist in waitlists
]
if waitlists_to_upsert:
if waitlists:
stmt = insert(Waitlist).values(
[{"email_id": email_id, **wl.dict()} for wl in waitlists_to_upsert]
[{"email_id": email_id, **wl.dict()} for wl in waitlists]
)
stmt = stmt.on_conflict_do_update(
constraint="uix_wl_email_name", set_=dict(stmt.excluded)
constraint="uix_wl_email_name",
set_={**dict(stmt.excluded), "update_timestamp": text("NOW()")},
)

db.execute(stmt)
Expand Down
8 changes: 1 addition & 7 deletions ctms/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@
UpdatedFirefoxAccountsInSchema,
)
from .mofo import MozillaFoundationInSchema, MozillaFoundationSchema
from .newsletter import (
NewsletterInSchema,
NewsletterSchema,
NewsletterTableSchema,
UpdatedNewsletterInSchema,
)
from .newsletter import NewsletterInSchema, NewsletterSchema, NewsletterTableSchema
from .product import ProductBaseSchema
from .stripe_customer import (
StripeCustomerCreateSchema,
Expand Down Expand Up @@ -69,7 +64,6 @@
)
from .waitlist import (
RelayWaitlistInSchema,
UpdatedWaitlistInSchema,
VpnWaitlistInSchema,
WaitlistInSchema,
WaitlistSchema,
Expand Down
10 changes: 1 addition & 9 deletions ctms/schemas/newsletter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime, timezone
from datetime import datetime
from typing import TYPE_CHECKING, Literal, Optional

from pydantic import UUID4, AnyUrl, Field
Expand Down Expand Up @@ -66,11 +66,3 @@ class NewsletterTableSchema(NewsletterBase):

class Config:
extra = "forbid"


class UpdatedNewsletterInSchema(NewsletterInSchema):
update_timestamp: datetime = Field(
default_factory=lambda: datetime.now(timezone.utc),
description="Newsletter subscription data update timestamp",
example="2021-01-28T21:26:57.511Z",
)
10 changes: 1 addition & 9 deletions ctms/schemas/waitlist.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime, timezone
from datetime import datetime
from typing import Optional

from pydantic import UUID4, AnyUrl, Field, root_validator
Expand Down Expand Up @@ -62,14 +62,6 @@ class Config:
WaitlistInSchema = WaitlistBase


class UpdatedWaitlistInSchema(WaitlistInSchema):
update_timestamp: datetime = Field(
default_factory=lambda: datetime.now(timezone.utc),
description="Waitlist data update timestamp",
example="2021-01-28T21:26:57.511Z",
)


class WaitlistTableSchema(WaitlistBase):
email_id: UUID4 = Field(
description=EMAIL_ID_DESCRIPTION,
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/test_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
create_fxa,
create_mofo,
create_newsletter,
create_or_update_contact,
delete_acoustic_field,
delete_acoustic_newsletters_mapping,
delete_acoustic_record,
Expand All @@ -38,6 +39,8 @@
MozillaFoundationInSchema,
NewsletterInSchema,
)
from ctms.schemas.contact import ContactPutSchema
from ctms.schemas.waitlist import WaitlistInSchema

# Treat all SQLAlchemy warnings as errors
pytestmark = pytest.mark.filterwarnings("error::sqlalchemy.exc.SAWarning")
Expand Down Expand Up @@ -810,6 +813,32 @@ def test_relations_on_stripe_subscription_items(
assert subscription_item.get_email_id() == email.email_id


def test_create_or_update_contact_timestamps(dbsession, email_factory):
email = email_factory(
newsletters=1,
waitlists=1,
)
dbsession.flush()

before_nl = email.newsletters[0].update_timestamp
before_wl = email.waitlists[0].update_timestamp

new_source = "http://waitlists.example.com"
putdata = ContactPutSchema(
email=EmailInSchema(email_id=email.email_id, primary_email=email.primary_email),
newsletters=[
NewsletterInSchema(name=email.newsletters[0].name, source=new_source)
],
waitlists=[WaitlistInSchema(name=email.waitlists[0].name, source=new_source)],
)
create_or_update_contact(dbsession, email.email_id, putdata, None)
dbsession.commit()

updated_email = get_email(dbsession, email.email_id)
assert updated_email.newsletters[0].update_timestamp != before_nl
assert updated_email.waitlists[0].update_timestamp != before_wl


def test_get_contacts_from_newsletter(dbsession, newsletter_factory):
existing_newsletter = newsletter_factory()
dbsession.flush()
Expand Down

0 comments on commit 7f33937

Please sign in to comment.