0

I am working on a codebase that uses sqlalchemy extensively and I am new to it. I am having trouble composing a sqlalchemy expression for a query that I want to write.

We have the following 3 tables:

  1. Product - (product_id, product_description, status, available)
  2. Category - (category_id, category_description)
  3. ProductCategoryLink - (product_id, category_id) [For many-to-many relationship]

I am running a query that gives me a product count per category. Some products are not assigned to any category and I want those products as well (category will be null in that case). I came up with the following query

select c.category_name, count(p.product_id)
from Product as p
left join ProductCategoryLink as pc
  on p.product_id = pc.product_id
left join Category as c      
  on c.category_id = pc.category_id
where p.store_id = 1111      
and p.status = 'ACTIVE'      
and p.available = 1
group by c.category_name; 

I have the following mappings in my orm file

class Product(Base):
    __tablename__ = 'Product'

    product_id          = Column(Integer, primary_key=True, name='product_id')
    product_description = Column(UnicodeText, name='description')
    available           = Column(Boolean, name='available')
    status              = Column(Unicode(length=255), name='status')

metadata = Base.metadata
# association table between product and category
product_category_link = Table('ProductCategoryLink', metadata,
        Column('product_id', Integer, ForeignKey('Product.product_id')),
        Column('category_id', Integer, ForeignKey('Category.category_id'))
)

class Category(Base):
    __tablename__ = 'Category'

    category_id                 = Column(Integer, primary_key=True, name='category_id')
    category_name               = Column(Unicode(length=255), name='category_name')
    products                    = relation('Product', secondary=product_category_link, backref='categories')

I came up with the following ORM expression

    query = session.query(Category.category_name, func.count(Product.product_id)).join(product_category_link).\
            join(Category).filter(
                and_(Product.store_id == self._store_id,
                    and_(Product.status == 'ACTIVE', Product.available == 1))).\
            group_by(Category.category_name).all()

The sql query that the above expression creates is not what I want.

sqlalchemy.exc.OperationalError: (OperationalError) (1066, "Not unique table/alias: 'Category'") 'SELECT `Category`.category_name AS `Category_category_name`, count(`Product`.product_id) AS count_1 \nFROM `Product`, `Category` INNER JOIN `ProductCategoryLink` ON `Category`.category_id = `ProductCategoryLink`.category_id INNER JOIN `Category` ON `Category`.category_id = `ProductCategoryLink`.category_id \nWHERE `Product`.store_id = %s AND `Product`.status = %s AND `Product`.available = %s GROUP BY `Category`.category_name' (1, 'ACTIVE', 1)

What am I doing wrong here?

1 Answer 1

1

When you join Category on Category it should have an alias.

See https://stackoverflow.com/a/1435186/708221

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.