Oh weird, it must have gotten erased before I pressed send...whoops!

On Nov 15, 2017 4:03 AM, "Simon King" <[email protected]> wrote:

> On Wed, Nov 15, 2017 at 12:10 AM, Mike Bayer <[email protected]>
> wrote:
> > On Tue, Nov 14, 2017 at 2:58 PM, Olaf <[email protected]> wrote:
> >> Hello everybody.
> >>
> >> Is it possible to have the following relationships between three classes
> >> (Animal, Car, Description) ?
> >>
> >> * An animal has an attribute description
> >> * A car has an attribute description
> >> * Each description contains his parent as an attribut. So parent can be
> a
> >> car or an animal
> >>
> >> Here is my code :
> >>
> >> from sqlalchemy import create_engine
> >> from sqlalchemy.orm import sessionmaker
> >> from sqlalchemy.ext.declarative import declarative_base
> >> from sqlalchemy import Column, Integer, String, ForeignKey
> >> from sqlalchemy.orm import relationship
> >>
> >>
> >> Base = declarative_base()
> >>
> >>
> >> class Description(Base):
> >>     __tablename__ = "descriptions"
> >>     id = Column(Integer, primary_key=True)
> >>     name = Column(String)
> >>
> >>
> >>     def __init__(self, name):
> >>         self.name = name
> >>         self.parent = None
> >>
> >>
> >>     def __repr__(self):
> >>         return self.name
> >>
> >>
> >> class Animal(Base):
> >>     __tablename__ = "animals"
> >>     id = Column(Integer, primary_key=True)
> >>     name = Column(String)
> >>     id_description = Column(Integer, ForeignKey("descriptions.id"),
> nullable
> >> = False)
> >>     description = relationship("Description", backref = "parent")
> >>
> >>
> >>     def __init__(self, name):
> >>          self.name = name
> >>
> >>
> >>     def __repr__(self):
> >>         return self.name
> >>
> >>
> >> class Car(Base):
> >>     __tablename__ = "cars"
> >>     id = Column(Integer, primary_key=True)
> >>     name = Column(String)
> >>     id_description = Column(Integer, ForeignKey("descriptions.id"),
> nullable
> >> = False)
> >>     description = relationship("Description", backref = "parent")
> >>
> >>
> >>     def __init__(self, name):
> >>         self.name = name
> >>
> >>
> >>     def __repr__(self):
> >>         return self.name
> >>
> >>
> >>
> >>
> >> engine = create_engine('YOUR DATABASE', echo = True)
> >>
> >>
> >> Base.metadata.create_all(engine)
> >>
> >> Session = sessionmaker(bind=engine)
> >> session = Session()
> >>
> >> rex = Animal("Rex")
> >> swift = Car("Suzuki Swift")
> >>
> >> d1 = Description("Rex is a good dog.")
> >> d2 = Description("What a beautiful car !")
> >>
> >> rex.description = d1
> >> d1.parent = rex
> >> swift.description = d2
> >> d2.parent = swift
> >>
> >> session.add(rex)
> >> session.add(swift)
> >> session.add(d1)
> >> session.add(d2)
> >>
> >> session.commit()
> >>
> >>
> >>
> >> Error :
> >>
> >> Traceback (most recent call last):
> >>   File "C:\Users\user\Desktop\test.py", line 56, in <module>
> >>     rex = Animal("Rex")
> >>   File "<string>", line 2, in __init__
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\orm\
> instrumentation.py",
> >> line 347, in _new_state_if_none
> >>     state = self._state_constructor(instance, self)
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\util\langhelpers.py",
> line
> >> 767, in __get__
> >>     obj.__dict__[self.__name__] = result = self.fget(obj)
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\orm\
> instrumentation.py",
> >> line 177, in _state_constructor
> >>     self.dispatch.first_init(self, self.class_)
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\event\attr.py", line
> 256,
> >> in __call__
> >>     fn(*args, **kw)
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\orm\mapper.py", line
> 3129,
> >> in _event_on_first_init
> >>     configure_mappers()
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\orm\mapper.py", line
> 3019,
> >> in configure_mappers
> >>     mapper._post_configure_properties()
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\orm\mapper.py", line
> 1810,
> >> in _post_configure_properties
> >>     prop.init()
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\orm\interfaces.py",
> line
> >> 184, in init
> >>     self.do_init()
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\orm\relationships.py",
> line
> >> 1661, in do_init
> >>     self._generate_backref()
> >>   File "C:\Python34\lib\site-packages\sqlalchemy\orm\relationships.py",
> line
> >> 1851, in _generate_backref
> >>     (backref_key, self, m))
> >> sqlalchemy.exc.ArgumentError: Error creating backref 'parent' on
> >> relationship 'Animal.description': property of that name exists on
> mapper
> >> 'Mapper|Description|descriptions'
> >>
> >>
> >> It seems impossible to link the classes to the same attribute "parent"
> in
> >> the class "Description". Is there a solution ?
> >
> >
> > you're attempting a pattern we call "generic association" (I've also
> > called it "polymorphic association") - a single destination item that
> > can be referred to by many types of objects.   I've documented three
> > ways of doing these, noting that one of them is a common pattern from
> > the Django / Rails world, though I don't recommend that one.   Unless
> > you need to query for descriptions across Dogs/Cars at the same time,
> > I'd go with table_per_related.   The mental exercise here is being OK
> > with the fact that there are more tables than you thought there would
> > be.    It "feels" wrong to have multiple tables with the same columns
> > but there's actually nothing wrong with it at all.   Your source code
> > need not have any repetition in it.
> >
>
> Here's the link to the docs:
>
> http://docs.sqlalchemy.org/en/latest/orm/examples.html#
> module-examples.generic_associations
>
> Simon
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example.  See  http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to