DmitrySemenov DmitrySemenov - 7 months ago 26
Python Question

sqlalchemy.exc.CircularDependencyError: Circular dependency detected

The business logic - One Category may have multiple (1:M) attributes, like Category "Memory" could have attributes Speed, Size, Type etc.

at the same time one Category could be sorted by the attribute value (this is stored inside Category.sortByAttribute - which is foreign key to LookupCategoryAttributes table.

Trying to construct it via SQLAlchemy, but getting circular dependency detected. What is wrong?

class Attribute(Base):

__tablename__ = "LookupCategoryAttributes"

types = ["date", "float", "integer", "select", "string", "text"]

# Properties
ID = Column(BigInteger, primary_key=True)
categoryID = Column(BigInteger, ForeignKey('LookupCategories.ID'), nullable=False )
attribute = Column(VARCHAR(255), nullable=False)
listValues = Column(VARCHAR(4000))
typeID = Column(VARCHAR(40), nullable=False)
isRequired = Column(SmallInteger, nullable=False, default=0)
displayInMenu = Column(SmallInteger, nullable=False, default=0)
displayInFilter = Column(SmallInteger, nullable=False, default=0)


class Category(Base):

__tablename__ = "LookupCategories"

# Properties
ID = Column(BigInteger, primary_key=True)
category = Column(VARCHAR(255), nullable=False)
description = Column(VARCHAR(1000), nullable=False)
parentCategoryID = Column(BigInteger, ForeignKey('LookupCategories.ID'))
leftPos = Column(Integer)
rightPos = Column(Integer)
sortByAttribute = Column(BigInteger, ForeignKey('LookupCategoryAttributes.ID'))
sortOrder = Column(SmallInteger, default=1)


# Relationships
ParentCategory = relationship("Category", uselist=False, remote_side=[ID], backref='SubCategories')
SortByAttribute = relationship("Attribute", uselist=False, foreign_keys=[sortByAttribute], primaryjoin="Attribute.ID==Category.sortByAttribute")
Attributes = relationship("Attribute", backref="Category", primaryjoin="Attribute.categoryID==Category.ID")


and then the code looks like this:

category = Category(record['Name'], extID=extID)
attr1 = Attribute(v)
attr2 = Attribute(v)

category.Attributes.append(attr1)
category.Attributes.append(attr2)
category.SortByAttribute = attr1


when I execute commit I get:

sqlalchemy.exc.CircularDependencyError: Circular dependency detected.

Answer

Okay found the answer - use post_update in relationship http://docs.sqlalchemy.org/en/latest/orm/relationship_persistence.html#post-update

so what I did is inside Category class is changed this:

SortByAttribute   = relationship("Attribute", uselist=False, foreign_keys=[sortByAttribute], primaryjoin="Attribute.ID==Category.sortByAttribute")

to this:

SortByAttribute   = relationship("Attribute", uselist=False, foreign_keys=[sortByAttribute], primaryjoin="Attribute.ID==Category.sortByAttribute", post_update=True)
Comments