🏦 Database Change: convert created utc to datetimez for viewers (#697)

* passed the test

* this works better

* Remove commented-out code.

* Remove commented-out code.

---------

Co-authored-by: Ben Rog-Wilhelm <zorba-github@pavlovian.net>
This commit is contained in:
Viet Than 2023-09-11 02:45:17 -05:00 committed by GitHub
parent 7b12fba945
commit e7926952b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 8 deletions

View file

@ -2,6 +2,7 @@ import time
from sqlalchemy import * from sqlalchemy import *
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.sql.functions import now
from files.classes.base import Base from files.classes.base import Base
from files.helpers.lazy import lazy from files.helpers.lazy import lazy
@ -13,17 +14,18 @@ class ViewerRelationship(Base):
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True) user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
viewer_id = Column(Integer, ForeignKey('users.id'), primary_key=True) viewer_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
last_view_utc = Column(Integer, nullable=False) last_view_datetimez = Column(DateTime(timezone=True), nullable=False, server_default=now())
Index('fki_view_viewer_fkey', viewer_id) Index('fki_view_viewer_fkey', viewer_id)
viewer = relationship("User", primaryjoin="ViewerRelationship.viewer_id == User.id", viewonly=True) viewer = relationship("User", primaryjoin="ViewerRelationship.viewer_id == User.id", viewonly=True)
def __init__(self, **kwargs): @property
if 'last_view_utc' not in kwargs: def last_view_utc(self):
kwargs['last_view_utc'] = int(time.time()) """
the last view timestamp in UTC seconds. Milliseconds are truncated/rounded down.
super().__init__(**kwargs) """
return int(self.last_view_datetimez.timestamp())
@property @property
@lazy @lazy

View file

@ -2,6 +2,7 @@ import io
import math import math
import time import time
from collections import Counter from collections import Counter
from datetime import datetime
from urllib.parse import urlparse from urllib.parse import urlparse
import gevent import gevent
@ -633,7 +634,7 @@ def following(v, username):
@auth_required @auth_required
def visitors(v): def visitors(v):
if v.admin_level < 2 and not v.patron: return render_template("errors/patron.html", v=v) if v.admin_level < 2 and not v.patron: return render_template("errors/patron.html", v=v)
viewers=sorted(v.viewers, key = lambda x: x.last_view_utc, reverse=True) viewers=sorted(v.viewers, key = lambda x: x.last_view_datetimez, reverse=True)
return render_template("viewers.html", v=v, viewers=viewers) return render_template("viewers.html", v=v, viewers=viewers)
@ -651,7 +652,7 @@ def u_username(username, v=None):
if v and v.id != u.id and (u.patron or u.admin_level > 1): if v and v.id != u.id and (u.patron or u.admin_level > 1):
view = g.db.query(ViewerRelationship).filter_by(viewer_id=v.id, user_id=u.id).one_or_none() view = g.db.query(ViewerRelationship).filter_by(viewer_id=v.id, user_id=u.id).one_or_none()
if view: view.last_view_utc = int(time.time()) if view: view.last_view_datetimez = datetime.utcnow()
else: view = ViewerRelationship(viewer_id=v.id, user_id=u.id) else: view = ViewerRelationship(viewer_id=v.id, user_id=u.id)
g.db.add(view) g.db.add(view)

View file

@ -0,0 +1,53 @@
"""Change to datetimez table viewers
Revision ID: bcfaec0d682a
Revises: a2fce4808e1d
Create Date: 2023-09-08 02:14:46.989072+00:00
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.sql.functions import now
# revision identifiers, used by Alembic.
revision = 'bcfaec0d682a'
down_revision = 'a2fce4808e1d'
branch_labels = None
depends_on = None
table_name = 'viewers'
from_column = 'last_view_utc'
to_column = 'last_view_datetimez'
def upgrade():
op.add_column(table_name, sa.Column(to_column, sa.DateTime(timezone=True), nullable=True, server_default=now()))
op.execute(f"""
UPDATE {table_name}
SET {to_column} =
CASE
WHEN {from_column} > 0 THEN
(timestamp 'epoch' + {from_column} * interval '1 second') at time zone 'utc'
ELSE NULL
END
""")
op.alter_column(table_name, to_column, nullable=False)
op.drop_column(table_name, from_column)
def downgrade():
"""
Downgrade will truncate the milliseconds.
"""
op.add_column(table_name, sa.Column(from_column, sa.Integer(), server_default=sa.text('0'), nullable=True))
op.execute(f"""
UPDATE {table_name}
SET {from_column} =
COALESCE(
EXTRACT(EPOCH FROM {to_column})::integer,
0
)
""")
op.alter_column(table_name, from_column, nullable=False)
op.drop_column(table_name, to_column)