Reputation: 157
Is there a way to be more explicit in SqlAlchemy ORM definitions by using class/member references instead of string constants without running into cyclic dependencies? One of the main benefits of an ORM is keeping things 'cleaner' and more maintainable than having string constants copied all over the place. This totally undermines that benefit.
A simple example from SqlAlchemy's docs, showing using string constants.
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship("Child")
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
I want to do this:
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship(Child)
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey(Parent.id))
This is generally legal, but the problem is that I run into cyclic dependencies with the necessary importing of Parent from Child and of Child from Parent (assuming they are in separate files). The best I can do is split the difference - and use strings on one end and do the explicit class w/import on the other end. Just feels icky.
Just wondering if I'm missing something or someone has some ways of accomplishing this.
Upvotes: 1
Views: 330
Reputation: 2087
As an alternative to string-based attributes, attributes may also be defined after all classes have been created. Just add them to the target class after the fact:
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey(Parent.id))
Parent.childen = relationship(Child)
Upvotes: 3