graphene-sqlalchemy
graphene-sqlalchemy copied to clipboard
Support for associationproxy
Hi,
I'm using graphene-sqlalchemy 2.0.0. I haven't found any documentation around association proxy support and my preliminary efforts into finding it in the code/docs/issues have proved futile. Are association proxies supported? If not, is there a plan to support them?
Thanks!
Seconding this, an initial google search came up dry and I'm wondering how to access related models via the association proxy.
This is important to me as well. Feels like a core feature that should be present.
Does anyone have a workaround for accessing AssociationProxy fields?
Edit: I gave AssociationProxy models their own nodes and linked the associated objects via one to one relationships.
Myself got at least part of it to work. I have Playlists and Media models, both many-to-many in both directions (one playlist can have many media, one media can be part of many playlists)
class Playlist(Base):
__tablename__ = 'playlists'
id = Column(BigInteger, primary_key=True)
#other fields here
media = association_proxy('media_associations', 'media')
class Media(Base):
__tablename__ = 'media'
id = Column(BigInteger, primary_key=True)
uid = Column(String(50), unique=True, index=True, nullable=False)
#other fields here
playlists = association_proxy('playlist_associations', 'playlist')
These two models are tied together via the association_proxy and
class PlaylistsMedia(Base):
__tablename__ = 'playlists_media'
id = Column(BigInteger, primary_key=True)
playlist_id = Column(BigInteger, ForeignKey('playlists.id'))
media_uid = Column(String, ForeignKey('media.uid'))
playlist = relationship(
'Playlist',
backref=backref("media_associations", cascade="all, delete-orphan"),
lazy='subquery'
)
media = relationship(
'Media',
backref=backref("playlist_associations", cascade="all, delete-orphan"),
lazy='subquery'
)
def __init__(self, playlist=None, media=None):
self.playlist = playlist
self.media = media
More details here, my implementation allows to have multiple "media" in one playlists.
On the Graph side
class PlaylistNode(SQLAlchemyObjectType):
class Meta:
model = Playlist
interfaces = (graphene.relay.Node, )
uid = graphene.String(description='Playlist uid generated at creation')
name = graphene.String(description='Playlist name as set by user')
# other fields here
media = graphene.List(MediaNode, description='collection of media associated to this playlist')
That's the Node for my Playlists model. Notice media, that will allow access to the associated media field I set in the model.
class Query(graphene.ObjectType):
"""Query objects for GraphQL API."""
class Meta:
interfaces = (graphene.relay.Node,)
node = graphene.relay.Node.Field()
viewer = graphene.Field(Viewer)
paginate_playlists = graphene.Field(lambda: graphene.List(PlaylistNode),
page=graphene.Int(required=True),
per_page=graphene.Int(required=True),
order_by=graphene.Int(required=True),
)
@staticmethod
def resolve_paginate_screens(root, info, **kwargs):
# here I query the Playlists model and return the items
Accessing that query from frontend with
query paginatePlaylists($page:Int!, $perPage: Int!, $orderBy: Int!){
paginatePlaylists(page:$page, perPage:$perPage, orderBy:$orderBy){
uid
name
status
dateCreated
scheduled
scheduleStart
scheduleStop
onPage
pagesCount
media{
id
uid
anyOtherFieldFromTheMediaNode
}
}
}
With all that I am able to query media associated to this playlist.
It would be nice to do the same the other way around but I can't add the PlaylistNode as a graphene.List to my MediaNode because scope logic:
- to add MediaNode in PlaylistNode I first need to create MediaNode and then PlaylistNode. Media can be added to Playlist but Playlist can't be added to Media (it was not yet defined). In SQLAlchemy I can use model names as string and not be limited by the fact that the Class was not yet defined
users_screens_association = Table('users_screens', Base.metadata,
Column('user_id', BigInteger, ForeignKey('users.id')),
Column('screen_id', String, ForeignKey('screens.device_id'))
)
Does anyone have a workaround for accessing AssociationProxy fields?
Edit: I gave AssociationProxy models their own nodes and linked the associated objects via one to one relationships.
ghost I just understood what you suggested there.
I can create as many nodes as I need from my Media and Playlist models. I can define and use them anywhere I need, and that's what I did and now I have a working Graph for my bidirectional many-to-many association-proxy relationship :D
#267 should solve this issue and will be merged soon!
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related topics referencing this issue.