可能有一些更好的方法,但您可以通过某种特殊的标记/非规范化来做到这一点。
例如,如果您将“thread_created_on”和“thread_id”添加到记录最顶部评论创建日期的 cmets,那么您可以通过平局获得您想要的。
# RCO - reverse chronological order
# CO - chronological order
comments = session.query(Comments).order_by(
Comments.thread_created_on.desc(), #threads together, RCO
(Comments.thread_id == None).desc(), # True then False: thread comment top
Comments.created_date_time.asc()) # nested comments CO)
from datetime import datetime
from sqlalchemy import (
create_engine,
UnicodeText,
Integer,
String,
ForeignKey,
UniqueConstraint,
update,
DateTime
)
from sqlalchemy.schema import (
Table,
Column,
MetaData,
)
from sqlalchemy.sql import select
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
Base = declarative_base()
engine = create_engine("sqlite://", echo=False)
class Comments(Base):
__tablename__ = 'comment'
id = Column(Integer, primary_key=True, index=True)
text = Column(String(1000))
created_on = Column(DateTime)
parent_id = Column(Integer, ForeignKey('comment.id'), nullable=True)
thread_created_on = Column(DateTime)
thread_id = Column(Integer, ForeignKey('comment.id'), nullable=True)
Base.metadata.create_all(engine)
def created_on(d):
return datetime.strptime(d, "%Y-%m-%d %H:%M:%S")
with Session(engine) as session:
d1 = created_on('2021-06-27 09:20:44')
thread1 = Comments(text='1', id=1, thread_created_on=d1, created_on=d1)
thread11 = Comments(text='1.1', id=6, parent_id=1, thread_id=1, thread_created_on=d1, created_on=created_on('2021-06-30 16:12:08'))
d2 = created_on('2021-06-27 10:00:04')
thread2 = Comments(text='2', id=2, thread_created_on=d2, created_on=d2)
thread21 = Comments(text='2.1', id=3, thread_id=2, parent_id=2, thread_created_on=d2, created_on=created_on('2021-06-27 12:33:41'))
thread211 = Comments(text='2.1.1', id=4, thread_id=2, parent_id=3, thread_created_on=d2, created_on=created_on('2021-06-28 20:07:09'))
thread22 = Comments(text='2.3', id=5, thread_id=2, parent_id=2, thread_created_on=d2, created_on=created_on('2021-06-29 06:22:11'))
d3 = created_on('2021-06-30 18:50:38')
thread3 = Comments(text='3', id=7, thread_created_on=d3, created_on=d3)
session.add_all([thread1, thread11, thread2, thread21, thread211, thread22, thread3])
session.commit()
from sqlalchemy import desc, nulls_first
comments = session.query(Comments).order_by(
Comments.thread_created_on.desc(), #threads together, RCO
(Comments.thread_id == None).desc(), # True then False: thread comment top
Comments.created_on.asc()) # nested comments CO)
props = ('id', 'text', 'created_on', 'parent_id', 'thread_id', 'thread_created_on')
fmt = ''.join(['%20s']*len(props))
print (fmt % props)
for comment in comments:
print (fmt % tuple([getattr(comment, prop) for prop in props]))
id text created_on parent_id thread_id thread_created_on
7 3 2021-06-30 18:50:38 None None 2021-06-30 18:50:38
2 2 2021-06-27 10:00:04 None None 2021-06-27 10:00:04
3 2.1 2021-06-27 12:33:41 2 2 2021-06-27 10:00:04
4 2.1.1 2021-06-28 20:07:09 3 2 2021-06-27 10:00:04
5 2.3 2021-06-29 06:22:11 2 2 2021-06-27 10:00:04
1 1 2021-06-27 09:20:44 None None 2021-06-27 09:20:44
6 1.1 2021-06-30 16:12:08 1 1 2021-06-27 09:20:44