Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy: Issue with One-to-One relationship object creation

I am new to SQLAlchemy and I was trying to run samples given in its documentation Basic Relationship Patterns - One to One Relationship. However as I try to instantiate the Parent class, I get into trouble.

Basically, what I have is:

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    child = relationship("Child", uselist=False, back_populates="parent")

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))
    parent = relationship("Child", back_populates="child")

p1 = Parent()

The tables are made and are listed by .tables at sqlite> prompt, but at the line p1 = Parent() I receive this:

sqlalchemy.exc.ArgumentError: reverse_property 'parent' on relationship Parent.child references relationship Child.parent, which does not reference mapper Mapper|Parent|parent

This doesn't happen for one-to-many relationship and for this piece of code I get [ ] and None printed out as I expect:

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String)

    addresses = relationship("Address", back_populates="user")

class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    email = Column(String)
    user_id = Column(Integer, ForeignKey('user.id'))

    user = relationship("User", back_populates="addresses")


u1 = User()
a1 = Address()

print(u1.addresses)
print(a1.user_id)

So, I don't quite understand what the SQLAlchemy error message is trying to tell me.

Can anyone help please?

like image 452
Gadfly4ever Avatar asked May 07 '26 02:05

Gadfly4ever


1 Answers

Ok, there is an obvious mistake in the document code. I'm posting this just in case anyone else runs to the same issue.

Basically, the relationship line in Child class, must be to the Parent class, and not to the Child class itself, as is in the documentation.

This code is corrected and works as expected (marked the modified part):

class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    child = relationship("Child", uselist=False, back_populates="parent")

class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))
    parent = relationship("Parent", back_populates="child")
                           ^^^^^^
p1 = Parent()
c1 = Child()

print(p1.id)
print(c1.parent_id)

Which prints out None and None as expected.

And that's all!

like image 58
Gadfly4ever Avatar answered May 08 '26 16:05

Gadfly4ever



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!