Skip to content

Instantly share code, notes, and snippets.

@meyt
Last active June 21, 2024 10:48
Show Gist options
  • Save meyt/ed85aeed598ed336fd499fd6a0739719 to your computer and use it in GitHub Desktop.
Save meyt/ed85aeed598ed336fd499fd6a0739719 to your computer and use it in GitHub Desktop.
SQLAlchemy vs Django ORM: Hybrid proprty (computed field)

Dynamic fields

sqlalchemy

class Page(Base):
    __tablename__ = 'pages'
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False)

class User(Base):
    __tablename__ = 'users'
    pages = relationship('Page', back_populates='user')
        
    @hybrid_property
    def page_count(self):
        return len(self.pages)

    @page_count.expression
    def page_count(cls):
        return (
            select([func.count(Page.id)])
            .where(Page.user_id == cls.id)
            .label('page_count')
        )

# create
user1 = User()
session.add(user1)
session.commit()

page1 = Page(user_id=user1.id)
session.add(page1)
session.commit()

# query
user1 = session.query(User).get(user1.id)
assert user1.pages_count == 1

page1 = session.query(Page).get(page1.id)
assert page1.user.pages_count == 1

users = session.query(User).filter(User.pages_count==1).all()
assert users[0].id == user1.id

django

class Page(models.Model):
    user = models.ForeginKey("User", on_delete=models.CASCADE, related_name="pages")
  
class UserManager(models.Manager):
    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).annotate(pages_count=mysubquery)

class User(models.Model):
    objects = UserManager()

# create
user1 = User.objects.create()
page1 = Page.objects.create(user=user1)

# query
user1 = User.objects.get(id=user1.id)
assert user1.pages_count == 1

# but this not works due to django doesn't use custom manager for relations
page1 = Page.objects.get(id=page1.id)
assert page1.user.pages_count

users = User.objects.filter(pages_count=1).all()
assert users[0].id == user1.id
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment