Skip to content

Commit

Permalink
docs: extend docs and add autodoc api docs
Browse files Browse the repository at this point in the history
  • Loading branch information
erikwrede committed Feb 24, 2023
1 parent 185a662 commit 686613d
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 3 deletions.
4 changes: 4 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
API Reference
====

.. automodule::graphene_sqlalchemy
5 changes: 4 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ Contents:
.. toctree::
:maxdepth: 0

tutorial
starter
inheritance
tips
examples
tutorial
api
2 changes: 1 addition & 1 deletion docs/inheritance.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Inheritance Examples

Create interfaces from inheritance relationships
------------------------------------------------
.. note:: If you're using `AsyncSession`, please check the chapter `Eager Loading & Using with AsyncSession`_.
.. note:: If you're using `AsyncSession`, please check the section `Eager Loading & Using with AsyncSession`_.
SQLAlchemy has excellent support for class inheritance hierarchies.
These hierarchies can be represented in your GraphQL schema by means
of interfaces_. Much like ObjectTypes, Interfaces in
Expand Down
43 changes: 43 additions & 0 deletions docs/relay.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Relay
====

:code:`graphene-sqlalchemy` comes with pre-defined
connection fields to quickly create a functioning relay API.
Using the :code:`SQLAlchemyConnectionField`, you have access to relay pagination,
sorting and filtering (filtering is coming soon!).

To be used in a relay connection, your :code:`SQLAlchemyObjectType` must implement
the :code:`Node` interface from :code:`graphene.relay`. This handles the creation of
the :code:`Connection` and :code:`Edge` types automatically.

The following example creates a relay-paginated connection:



.. code:: python
class Pet(Base):
__tablename__ = 'pets'
id = Column(Integer(), primary_key=True)
name = Column(String(30))
pet_kind = Column(Enum('cat', 'dog', name='pet_kind'), nullable=False)
class PetNode(SQLAlchemyObjectType):
class Meta:
model = Pet
interfaces=(Node,)
class Query(ObjectType):
all_pets = SQLAlchemyConnectionField(PetNode.connection)
To disable sorting on the connection, you can set :code:`sort` to :code:`None` the
:code:`SQLAlchemyConnectionField`:


.. code:: python
class Query(ObjectType):
all_pets = SQLAlchemyConnectionField(PetNode.connection, sort=None)
118 changes: 118 additions & 0 deletions docs/starter.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
Getting Started
====

Welcome to the graphene-sqlalchemy documentation!
Graphene is a powerful Python library for building GraphQL APIs,
and SQLAlchemy is a popular ORM (Object-Relational Mapping)
tool for working with databases. When combined, graphene-sqlalchemy
allows developers to quickly and easily create a GraphQL API that
seamlessly interacts with a SQLAlchemy-managed database.
It is fully compatible with SQLAlchemy 1.4 and 2.0.
This documentation provides detailed instructions on how to get
started with graphene-sqlalchemy, including installation, setup,
and usage examples.

Installation
------------

To install :code:`graphene-sqlalchemy`, just run this command in your shell:

.. code:: bash
pip install --pre "graphene-sqlalchemy"
Examples
--------

Here is a simple SQLAlchemy model:

.. code:: python
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class UserModel(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)
last_name = Column(String)
To create a GraphQL schema for it, you simply have to write the
following:

.. code:: python
import graphene
from graphene_sqlalchemy import SQLAlchemyObjectType
class User(SQLAlchemyObjectType):
class Meta:
model = UserModel
# use `only_fields` to only expose specific fields ie "name"
# only_fields = ("name",)
# use `exclude_fields` to exclude specific fields ie "last_name"
# exclude_fields = ("last_name",)
class Query(graphene.ObjectType):
users = graphene.List(User)
def resolve_users(self, info):
query = User.get_query(info) # SQLAlchemy query
return query.all()
schema = graphene.Schema(query=Query)
Then you can simply query the schema:

.. code:: python
query = '''
query {
users {
name,
lastName
}
}
'''
result = schema.execute(query, context_value={'session': db_session})
It is important to provide a session for graphene-sqlalchemy to resolve the models.
In this example, it is provided using the GraphQL context. See :ref:`querying` for
other ways to implement this.

You may also subclass SQLAlchemyObjectType by providing
``abstract = True`` in your subclasses Meta:

.. code:: python
from graphene_sqlalchemy import SQLAlchemyObjectType
class ActiveSQLAlchemyObjectType(SQLAlchemyObjectType):
class Meta:
abstract = True
@classmethod
def get_node(cls, info, id):
return cls.get_query(info).filter(
and_(cls._meta.model.deleted_at==None,
cls._meta.model.id==id)
).first()
class User(ActiveSQLAlchemyObjectType):
class Meta:
model = UserModel
class Query(graphene.ObjectType):
users = graphene.List(User)
def resolve_users(self, info):
query = User.get_query(info) # SQLAlchemy query
return query.all()
schema = graphene.Schema(query=Query)
More complex inhertiance using SQLAlchemy's polymorphic models is also supported.
You can check out :doc:`inheritance` for a guide.
2 changes: 1 addition & 1 deletion docs/tips.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tips

Querying
--------

.. _querying:
In order to make querying against the database work, there are two alternatives:

- Set the db session when you do the execution:
Expand Down

0 comments on commit 686613d

Please sign in to comment.