API¶
Anything documented here is part of the public API that Magql-SQLAlchemy provides, unless otherwise indicated. Anything not documented here is considered internal or private and may change at any time.
Models¶
- class magql_sqlalchemy.ModelGroup(managers=None)¶
Collects multiple model managers and manages higher-level APIs such as search and check delete.
Typically there will be one group for all the models. If more than one group is used for some reason, the field names for its
search
andcheck_delete
instances should be changed.- Parameters:
managers (list[ModelManager[t.Any]] | None) – The model managers that are part of this group.
- manager_class¶
alias of
ModelManager
- managers: dict[str, ModelManager[Any]]¶
Maps SQLAlchemy model names to their
ModelManager
instance. Useadd_manager()
to add to this.
- check_delete: CheckDelete¶
The
CheckDelete
instance models will be registered on.
- classmethod from_declarative_base(base, *, search=True)¶
Create a group of model managers for all models in the given SQLAlchemy declarative base class.
- Parameters:
base (type[DeclarativeBase]) – The SQLAlchemy declarative base class.
search (bool | set[type[DeclarativeBase] | str]) – A bool to enable or disable search for all models. Or a set of models or names.
- Return type:
- add_manager(manager)¶
Add another model manager after the group was created.
- Parameters:
manager (ModelManager[Any]) – The model manager to add.
- Return type:
None
- class magql_sqlalchemy.ModelManager(model, search=False)¶
The API for a single SQLAlchemy model class. Generates Magql types, fields, resolvers, etc. These are exposed as attributes on this manager, and can be further customized after generation.
- Parameters:
- item_factory¶
alias of
ItemResolver
- list_factory¶
alias of
ListResolver
- create_factory¶
alias of
CreateResolver
- update_factory¶
alias of
UpdateResolver
- delete_factory¶
alias of
DeleteResolver
- object: Object¶
The object type and fields representing the model and its columns. The type name is the model name.
type Model { id: Int! name: String! }
- item_field: Field¶
Query that selects a row by id from the database. Will return null if the id doesn’t exist. The field name is the snake case model name with
_item
appended. UsesItemResolver
.type Query { model_item(id: Int!): Model }
- list_result: Object¶
The object type representing the result of the list query. The type name is the model name with
ListResult
appended.ListResult
is the Python type corresponding to this Magql type.
- list_field: Field¶
Query that selects multiple rows from the database. The field name is the snake case model name with
_list
appended. UsesListResolver
.type Query { model_list( filter: [[FilterItem!]!], sort: [String!], page: Int, per_page: Int ): ModelListResult! }
- create_field: Field¶
Mutation that inserts a row into the database. The field name is the snake case model name with
_create
appended. An argument is generated for each column in the model except the primary key. An argument is required if its column is not nullable and doesn’t have a default. UsesCreateResolver
.type Mutation { model_create(name: String!): Model! }
- update_field: Field¶
Mutation that updates a row in the database. The field name is the snake case model name with
_update
appended. An argument is generated for each column in the model. The primary key argument is required, all others are not. Columns are not updated if their argument is not given. UsesUpdateResolver
.type Mutation { model_update(id: Int!, name: String): Model! }
- delete_field: Field¶
Mutation that deletes a row from the database. The field name is the snake case model name with
_delete
appended. UsesDeleteResolver
.type Mutation { model_delete(id: Int!): Boolean! }
- search_provider: SearchProvider | None = None¶
A global search provider function. Enabling search will create a
ColumnSearchProvider
that checks if any of the model’s string columns contains the search term. This can be set to a custom function to change search behavior.
- register(schema)¶
Register this manager’s query and mutation fields on the given
magql.Schema
instance.- Parameters:
schema (Schema) – The schema instance to register on.
- Return type:
None
- register_search(search)¶
If a search provider is enabled for this manager, register it on the given
Search
instance.Typically the search instance is managed by the
ModelGroup
, which will register it on a schema.- Parameters:
search (Search) – The search instance to register on.
- Return type:
None
Resolvers¶
- class magql_sqlalchemy.resolvers.ItemResolver(model)¶
Get a single row from the database by id. Used by
ModelManager.item_field
.id
is the only GraphQL argument. Returns a single model instance, orNone
if the id wasn’t found.- Parameters:
model (type[M]) – The SQLAlchemy model.
- build_query(parent, info, **kwargs)¶
Build the query to execute.
- Parameters:
parent (Any)
info (GraphQLResolveInfo)
kwargs (Any)
- Return type:
- class magql_sqlalchemy.resolvers.ListResolver(model)¶
Get a list of rows from the database, with support for filtering, sorting, and pagination. If any relationships, arbitrarily nested, are selected, they are eagerly loaded to Used by
ModelManager.list_field
. Returns aListResult
, which has the list of model instances selected for this page, as well as the total available rows.Pagination is always applied to the query to avoid returning thousands of results at once for large data sets. The default
page
is 1. The defaultper_page
is 10, with a max of 100.The
sort
argument is a list of column names from theModelManager.sort
enum. By default the rows are sorted by their primary key column, otherwise the order wouldn’t be guaranteed consistent across pages. A name that begins with-
sorts in descending order.Filtering applies one or more filter rules to the query. The
filter
argument is a list of lists of rules. Each rule is a{path, op, not, value}
dict. The rules in a list will be combined withAND
, and the lists will be combined withOR
. Thepath
in a rule is the name of a column attribute on the model likename
, or a dotted path to an arbitrarily nested relationship’s column likeuser.friend.color.name
. Differentop
names are available based on the column’s type. Thevalue
can be any JSON data that the op understands. Most ops support a list of values in addition to a single value. Seeapply_filter_item()
andtype_ops
.If any relationships are selected anywhere in the GraphQL query, SQLAlchemy eager loads are generated them. This makes resolving the graph very efficient by letting SQLAlchemy preload related data rather than issuing individual queries for every attribute access.
- Parameters:
model (type[M]) – The SQLAlchemy model.
- build_query(parent, info, **kwargs)¶
Build the query to execute.
- Parameters:
parent (Any)
info (GraphQLResolveInfo)
kwargs (Any)
- Return type:
- get_count(session, query)¶
After generating the query with any filters, get the total row count for pagination purposes. Remove any eager loads, sorts, and pagination, then execute a SQL
count()
query.
- class magql_sqlalchemy.resolvers.CreateResolver(model)¶
Create a new row in the database. Used by
ModelManager.create_field
. The field has arguments for each of the model’s column attributes. An argument is not required if its column is nullable or has a default. Unique constraints on will already be validated. Returns the new model instance.- Parameters:
model (type[M]) – The SQLAlchemy model.
- prepare_item(info, kwargs)¶
Get and modify the model instance in the SQLAlchemy session, but do not commit the session. Calling the resolver calls this and then calls commit, but this can be used directly when wrapping the resolver with other behavior.
Added in version 1.1.
- Parameters:
info (GraphQLResolveInfo)
- Return type:
M
For all relationship arguments, replace the id values with their model instances.
- get_item(info, kwargs)¶
Get the model instance by primary key value.
- Parameters:
info (GraphQLResolveInfo)
- Return type:
M
- class magql_sqlalchemy.resolvers.UpdateResolver(model)¶
Updates a row in the database by id. Used by
ModelManager.update_field
. The field has arguments for each of the model’s column attributes. Only the primary key argument is required. Columns are only updated if a value is provided, which is distinct from setting the value toNone
. Unique constraints will already be validated. Returns the updated model instance.- Parameters:
model (type[M]) – The SQLAlchemy model.
- prepare_item(info, kwargs)¶
Get and modify the model instance in the SQLAlchemy session, but do not commit the session. Calling the resolver calls this and then calls commit, but this can be used directly when wrapping the resolver with other behavior.
Added in version 1.1.
- Parameters:
info (GraphQLResolveInfo)
- Return type:
M
For all relationship arguments, replace the id values with their model instances.
- get_item(info, kwargs)¶
Get the model instance by primary key value.
- Parameters:
info (GraphQLResolveInfo)
- Return type:
M
- class magql_sqlalchemy.resolvers.DeleteResolver(model)¶
Deletes a row in the database by id. Used by
ModelManager.update_field
. Use theCheckDelete
API first to check if the row can be safely deleted. ReturnsTrue
.- Parameters:
model (type[M]) – The SQLAlchemy model.
For all relationship arguments, replace the id values with their model instances.
- get_item(info, kwargs)¶
Get the model instance by primary key value.
- Parameters:
info (GraphQLResolveInfo)
- Return type:
M
- prepare_item(info, kwargs)¶
Get and modify the model instance in the SQLAlchemy session, but do not commit the session. Calling the resolver calls this and then calls commit, but this can be used directly when wrapping the resolver with other behavior.
Added in version 1.1.
- Parameters:
info (GraphQLResolveInfo)
- Return type:
M
- magql_sqlalchemy.filters.type_ops: dict[type[TypeEngine], dict[str, Callable[[Column[Any], list[Any]], Any]]] = {<class 'sqlalchemy.sql.sqltypes.Boolean'>: {'eq': <function <lambda>>}, <class 'sqlalchemy.sql.sqltypes.DateTime'>: {'eq': <function op_eq>, 'ge': <function <lambda>>, 'gt': <function <lambda>>, 'le': <function <lambda>>, 'lt': <function <lambda>>}, <class 'sqlalchemy.sql.sqltypes.Enum'>: {'eq': <function op_eq>}, <class 'sqlalchemy.sql.sqltypes.Float'>: {'eq': <function op_eq>, 'ge': <function <lambda>>, 'gt': <function <lambda>>, 'le': <function <lambda>>, 'lt': <function <lambda>>}, <class 'sqlalchemy.sql.sqltypes.Integer'>: {'eq': <function op_eq>, 'ge': <function <lambda>>, 'gt': <function <lambda>>, 'le': <function <lambda>>, 'lt': <function <lambda>>}, <class 'sqlalchemy.sql.sqltypes.String'>: {'eq': <function op_eq>, 'like': <function op_like>}}¶
Maps SQLAlchemy column types to available filter operations. The operations map names to callables that generate a SQL expression.
Search¶
- class magql_sqlalchemy.search.ColumnSearchProvider(model)¶
A search provider for
Search
which checks if any string columns in the given SQLAlchemy model contains the case-insensitive search value.This is generated by
ModelManager
if search is enabled for that model.- Parameters:
model (type[t.Any]) – SQLAlchemy model class.
- model¶
The SQLAlchemy model being searched.
Check Delete¶
- class magql_sqlalchemy.check_delete.CheckDelete(managers, field_name='check_delete')¶
Query field and resolver that shows what would be affected by deleting a row, without actually deleting it. Rather than creating a separate query per model, this is a generic API using the model name and id.
The resolver returns
CheckDeleteResult
, which is a collection ofSearchResult
items.Affected - Items that will have references to the deleted item removed, such as many-to-many or nullable foreign keys.
Deleted - Items that will be deleted along with the deleted item.
Prevented - Items that will not be deleted or have references removed prevent the item from being deleted.
This shouldn’t need to be created directly, it’s managed by
ModelGroup
.- Parameters:
managers (dict[str, ModelManager[t.Any]]) – Maps model names to managers.
field_name (str) – The name to use for this field in the top-level query object.
- managers¶
Maps model names to managers. These are the models that can be checked.
- register(schema)¶
Register the field on the given
Search
instance.- Parameters:
schema (Schema) – The schema instance to register on.
- Return type:
None
- field: nodes.Field¶
The query field.
type Query { check_delete(type: String!, id: ID!): CheckDeleteResult! }
Validators¶
- class magql_sqlalchemy.validators.ItemExistsValidator(model, key, col)¶
Validate that an id exists for a model in the database. Used by update and delete mutations.
- class magql_sqlalchemy.validators.ListExistsValidator(model, key, col)¶
Validate that a list of ids all exist for a model in the database. Used by update mutations for to-many relationships. Each id that does not exist will generate its own error message.
- class magql_sqlalchemy.validators.UniqueValidator(model, columns, pk_name, pk_col)¶
Validate that a value for a column is unique, or values for a group of columns are unique together. Used by create and update mutations.
For create mutations, optional arguments that aren’t provided will use the column’s default. However, this can’t work for columns with callable defaults.
For update mutations, the row won’t conflict with itself. Optional arguments that aren’t provided will use the row’s data.
- magql_sqlalchemy.pagination.validate_page(info, value, data)¶
Validate the
page
argument toListResolver
.- Parameters:
info (GraphQLResolveInfo)
value (int)
data (Any)
- Return type:
None
- class magql_sqlalchemy.pagination.PerPageValidator(max_per_page=100)¶
Validate the
per_page
argument toListResolver
.- Parameters:
max_per_page (int | None) – The maximum allowed value, or
None
for no maximum.