Hi there, 

I'm trying to create a relationship for a Mxin that is agnostic to what the 
primary key of the mixed object is.

Basically we have this:

class TransitionBase(SurrogatePK, Model):
    __abstract__ = True

    obj_id = Column(String, nullable=False, index=True)
    state = Column(String, nullable=False, index=True)
    ...(more stuff)...

class HasStateMixin:
    @staticmethod
    def get_state_class() -> Type[TransitionBase]:
        raise NotImplementedError()

    @declared_attr
    def transitions(cls) -> List[TransitionBase]:
        state_cls = cls.get_state_class()
        return relationship(
            state_cls,
            primaryjoin=foreign(state_cls.obj_id) == remote(cls.id),  # 
type: ignore
            order_by=state_cls.id.desc(),
        )

And it works well, as long as the `id` property is a normal Column. Eg:

class Transition(TransitionBase):
    __tablename__ = ''transitions'


class Obj(Model, HasStateMachineMixin):
    __tablename__ = 'obj'
    __table_args__ = {'schema': test_schema}

    id = Column(String, primary_key=True)

    @staticmethod
    def get_state_class() -> Type[TransitionBase]:
        return Transition

But now I have a case where the primary key of the mixed class is three 
columns. My first instinct was to use a hybrid property like this:

class ThreePrimaryKeys(HasStateMachineMixin):
    a = Column(String, primary_key=True)
    b = Column(String, primary_key=True)
    c = Column(String, primary_key=True)

    @hybrid_property
    def id(self):
        return f'/{self.a}/{self.b}/{self.c}'

    @id.expression
    def id(cls):
        return func.concat(
            '/', cls.a, '/', cls.b, '/', cls.c,
        )

But that doesn't work: when I create a ThreePrimaryKeys() and then call 
obj.transitions.append(MyTransition(state='foo')) it doesn't properly 
persist the full concatenated ID - weirdly, it just uses column 'c' (or the 
equivalent - type names have been changed to protect the innocent)

My question is: should this work? And if so, what am I doing wrong? If not, 
do you have an alternate approach?

Thanks in advance,

Bobby

-- 
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 sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/0083c5d4-cd66-4346-8108-f85a8909d69an%40googlegroups.com.

Reply via email to