Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Input Arguments from SQLAlchemy Class? #112

Open
alexisrolland opened this issue Feb 9, 2018 · 3 comments
Open

Generate Input Arguments from SQLAlchemy Class? #112

alexisrolland opened this issue Feb 9, 2018 · 3 comments

Comments

@alexisrolland
Copy link

Hello,
Do you know if it's possible to generate input arguments dynamically from the SQLAlchemy class that will be transformed by the mutation?
Example:

My input arguments for a CreatePerson mutation look like this:

class CreatePersonInput(graphene.InputObjectType):
    """Arguments to create a person."""
    name = graphene.String(required=True, description="Name of the person to be created.")
    height = graphene.String(default_value="unknown", description="Height of the person to be created.")
    mass = graphene.String(default_value="unknown", description="Mass of the person to be created.")
    hair_color = graphene.String(default_value="unknown", description="Hair color of the person to be created.")
    skin_color = graphene.String(default_value="unknown", description="Skin color of the person to be created.")
    eye_color = graphene.String(default_value="unknown", description="Eye color of the person to be created.")
    birth_year = graphene.String(default_value="unknown", description="Birth year of the person to be created.")
    gender = graphene.String(default_value="unknown", description="Gender of the person to be created.")
    planet_id = graphene.ID(default_value="unknown", description="Global Id of the planet from which the person to be created comes from.")
    url = graphene.String(default_value="unknown", description="URL of the person in the Star Wars API.")


class CreatePerson(graphene.Mutation):
    """Mutation to create a person."""
    person = graphene.Field(lambda: People, description="Person created by this mutation.")

    class Arguments:
        input = CreatePersonInput(required=True)

...

In the meantime, the input arguments for my UpdatePerson mutation look like this:

class UpdatePersonInput(graphene.InputObjectType):
    """Arguments to update a person."""
    id = graphene.ID(required=True)
    name = graphene.String()
    height = graphene.String()
    mass = graphene.String()
    hair_color = graphene.String()
    skin_color = graphene.String()
    eye_color = graphene.String()
    birth_year = graphene.String()
    gender = graphene.String()
    planet_id = graphene.ID()
    url = graphene.String()


class UpdatePerson(graphene.Mutation):
    """Update a person."""
    person = graphene.Field(lambda: People, description="Person updated by this mutation.")

    class Arguments:
        input = UpdatePersonInput(required=True)

...

Finally, my SQLAlchemy class look like this:

class ModelPeople(Base):
    """People model."""

    __tablename__ = 'people'

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String)
    height = Column('height', String)
    mass = Column('mass', String)
    hair_color = Column('hair_color', String)
    skin_color = Column('skin_color', String)
    eye_color = Column('eye_color', String)
    birth_year = Column('birth_year', String)
    gender = Column('gender', String)
    planet_id = Column('planet_id', Integer, ForeignKey('planet.id'))
    created = Column('created', String)
    edited = Column('edited', String)
    url = Column('url', String)

...

This is all pretty redundant and it would be ideal if we could just reuse the SQLAlchemy class attributes in the InputObjectType

@alexisrolland
Copy link
Author

I was able to factorize my code a little bit by creating a new class where I define attributes description only once. Then I supply this new class as a parent class of the following classes:

  • class People(SQLAlchemyObjectType, PeopleAttribute) : used for GraphQL queries
  • class CreatePersonInput(graphene.InputObjectType, PeopleAttribute) : used to define inputs for GraphQL create mutation
  • class UpdatePersonInput(graphene.InputObjectType, PeopleAttribute) : used to define inputs for GraphQL create mutation

Here is the code:

# Create a generic class to mutualize description of people attributes for both queries and mutations
class PeopleAttribute:
    name = graphene.String(required=True, description="Name of the person.")
    height = graphene.String(default_value="unknown", description="Height of the person.")
    mass = graphene.String(default_value="unknown", description="Mass of the person.")
    hair_color = graphene.String(default_value="unknown", description="Hair color of the person.")
    skin_color = graphene.String(default_value="unknown", description="Skin color of the person.")
    eye_color = graphene.String(default_value="unknown", description="Eye color of the person.")
    birth_year = graphene.String(default_value="unknown", description="Birth year of the person.")
    gender = graphene.String(default_value="unknown", description="Gender of the person.")
    planet_id = graphene.ID(default_value="unknown", description="Global Id of the planet from which the person comes from.")
    url = graphene.String(default_value="unknown", description="URL of the person in the Star Wars API.")


class People(SQLAlchemyObjectType, PeopleAttribute):
    """People node."""

    class Meta:
        model = ModelPeople
        interfaces = (graphene.relay.Node,)


class CreatePersonInput(graphene.InputObjectType, PeopleAttribute):
    """Arguments to create a person."""
    pass


class UpdatePersonInput(graphene.InputObjectType, PeopleAttribute):
    """Arguments to update a person."""
    id = graphene.ID(required=True, description="Global Id of the person.")

@alexisrolland
Copy link
Author

alexisrolland commented Feb 15, 2018

Does anyone has a better way of doing this?
I have also posted the question here : https://stackoverflow.com/questions/48806710/generate-graphene-mutation-inputs-from-sqlalchemy-class-attributes

@arlobryer
Copy link

See this also: #29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants