Skip to content

Commit 1e2932f

Browse files
committed
initial docs
1 parent 230fdb3 commit 1e2932f

File tree

8 files changed

+187
-8
lines changed

8 files changed

+187
-8
lines changed

docs/check_delete.md

Lines changed: 0 additions & 2 deletions
This file was deleted.

docs/filters.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,57 @@
11
List Query Filters
22
==================
3+
4+
The `model_list` query field generated for each model supports building
5+
arbitrarily complex filters with the `filter` argument.
6+
7+
The `filter` argument takes a list of lists of filter item structures. Each
8+
filter item in a list is combined with `AND`. Each list of filter items is
9+
combined with `OR`. As a shortcut, GraphQL will wrap a single item in the two
10+
lists implicitly.
11+
12+
Each filter item has the following keys:
13+
14+
- `path`, a column name on the model being queried, or a dotted path that
15+
can access columns through one or more relationships from the initial model.
16+
- `op`, an operator name, which is dependant on the column's type. See the
17+
next section for the default operators.
18+
- `not`, an optional boolean to negate the filter. For example, the `eq` op
19+
can be turned into `not eq` without needing to define a separate operator.
20+
- `value`, the value to filter on. In simple cases, this will be a single
21+
value, but some operators like `eq` support a list of values as a shortcut
22+
to specifying multiple filter items. It can be arbitrary JSON data to
23+
support anything custom operators might use.
24+
25+
26+
Operators
27+
---------
28+
29+
Different filter operations are available depending on the type of the column.
30+
The {data}`.filters.type_ops` data structure maps SQLAlchemy types to operation
31+
names to functions that apply the operation.
32+
33+
- {class}`~sqlalchemy.types.String`
34+
- `eq`, exact equality. Accepts a single value or list.
35+
- `like`, case-insensitive partial match. Accepts a single value or list.
36+
SQL wildcard characters are escaped.
37+
- {class}`~sqlalchemy.types.Integer`, {class}`~sqlalchemy.types.Float`,
38+
{class}`~sqlalchemy.types.DateTime`
39+
- `eq`, exact equality. Accepts a single value or list.
40+
- `lt`, less than a single value.
41+
- `le`, less than or equal to a single value.
42+
- `ge`, greater than or equal to a single value.
43+
- `gt`, greater than a single value.
44+
- {class}`~sqlalchemy.types.Boolean`
45+
- `eq`, true or false.
46+
- {class}`~sqlalchemy.types.DateTime`
47+
- `eq`, exact equality. Accepts a single value or list.
48+
49+
50+
Custom Operators
51+
----------------
52+
53+
You can add operators for other types, or add to the operators for an existing
54+
type, by modifying the {data}`.filter.type_ops` structure. An operator function
55+
takes the SQLAlchemy column being filtered, and the list of values (will be a
56+
list even if a single value was given), and should return a SQLAlchemy
57+
expression that can be used with `WHERE`.

docs/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ provides:
3030
3131
start
3232
filters
33-
search
34-
check_delete
33+
q-search
34+
q-check_delete
3535
model
3636
api
3737
changes

docs/model.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,31 @@ in {class}`magql.NonNull` appropriately for field and argument types.
5353
Relationships
5454
-------------
5555

56+
For each relationship, a field will be generated on the object with the type of
57+
the related model's object. To-one relationships will be single objects, to-many
58+
relationships will be wrapped in {class}`magql.List`.
5659

60+
Relationships are also available as arguments to the `model_create` and
61+
`model_update` mutation fields. In this case, they accept primary key value (or
62+
values), and validate that the referenced rows exists.
63+
64+
When querying and selecting nested objects and fields across relationships,
65+
Magql-SQLAlchemy will generate efficient eager loads for the selected
66+
relationships. This means SQLAlchemy will emit a minimal number of queries to
67+
load all data. You can observe this by turing `echo=True` on for your
68+
SQLAlchemy engine.
5769

5870

5971
Validators
6072
----------
73+
74+
Two types of validators are automatically generated as needed:
75+
76+
- For each column marked `unique=True`, and for each `UniqueConstraint` that
77+
applies to one or more columns, a validator will check that the values given
78+
during create or update are unique. The validator can handle multiple
79+
columns, defaults, and existing values for partial update. See
80+
{class}`.UniqueValidator`.
81+
- For each relationship, a validator will check that the given primary keys
82+
exist, for to-one and to-many relationships. See
83+
{class}`.ItemExistsValidator` and {class}`.ListExistsValidator`.

docs/q-check_delete.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
Preview Delete Effects Query
2+
============================
3+
4+
Magql-SQLAlchemy provides a `check_delete` query field that can show the effects
5+
of deleting a row. This is done purely through introspection and does not
6+
perform an actual deletion. This can be used in a UI to show an "Are you sure
7+
you want to delete?" prompt with helpful information, or an explanation about
8+
why something can't be deleted.
9+
10+
11+
The Query and Results
12+
---------------------
13+
14+
The field takes two arguments, `type` is the name of the model, and `id` is the
15+
primary key of the row. It returns three lists, with items in the same format
16+
as {doc}`q-search`.
17+
18+
- `affected`, model rows that would change somehow. A nullable to-one
19+
relationship is cleared, or the row is removed from a to-many relationship.
20+
- `deleted`, model rows that would be deleted along with the checked row. Rows
21+
in a relationship that has `cascade='delete'` (or usually `all`) set.
22+
- `prevented`, model rows that would cause the deletion to fail. A non-null
23+
relationship.
24+
25+
The items in each list have the following keys:
26+
27+
- `type`, the name of the model class.
28+
- `id`, the primary key of the row.
29+
- `value`, the string representation of the model row (`str(item)`).
30+
- `extra`, currently unused, arbitrary extra information about the row.
31+
32+
33+
How It Works
34+
------------
35+
36+
The query finds the SQLAlchemy model by name, then selects the row by id from
37+
the database. Then it examines all the relationship properties of the model to
38+
build the lists described above. Therefore, only data with SQLAlchemy
39+
`relationship` properties can be returned in the result.
40+
41+
It's recommended that all relationships are two-way, with a property on each
42+
model and with `back_populates` set on both. If one side does not have a
43+
relationship, then checking its deletion cannot warn about affected rows or
44+
that the database will raise an error.
45+
46+
47+
Excluding Models
48+
----------------
49+
50+
If you don't want to be able check a given model, you can remove it from the
51+
{class}`.CheckDelete.managers` map. However, it may still show up in the results
52+
of deleting other models if they have relationships to it.
53+
54+
```python
55+
del model_group.check_delete.managers["UserSession"]
56+
```

docs/q-search.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
Global Search Query
2+
===================
3+
4+
Magql provides a `search` query field that will perform a global search using
5+
registered providers. Magql-SQLAlchemy registers a provider for each model that
6+
will search all string columns.
7+
8+
9+
The Query and Results
10+
---------------------
11+
12+
The `search` query field takes one argument, `value`, the string to search for.
13+
It returns a list of items.
14+
15+
The items in the list have the following keys:
16+
17+
- `type`, the name of the model class.
18+
- `id`, the primary key of the row.
19+
- `value`, the string representation of the model row (`str(item)`).
20+
- `extra`, currently unused, arbitrary extra information about the row.
21+
22+
Using the `type` and `id`, a UI could present search results that link to that
23+
item.
24+
25+
26+
Disabling for a Model
27+
---------------------
28+
29+
When using {class}`.ModelGroup.from_declarative_base`, it takes a `search`
30+
argument to control what models are searchable.
31+
32+
By default, `search` is `True`, which generates a search provider for ever
33+
model. You can reassign {attr}`.ModelManager.search_provider` to `None` to
34+
disable search for that model. If you set `search` to `False`, no providers will
35+
be generated.
36+
37+
You can pass a set of model classes and/or model names to `search` to
38+
generate providers only for those models.
39+
40+
41+
Customizing a Provider
42+
----------------------
43+
44+
The default search provider for each model is {class}`.ColumnSearchProvider`,
45+
which generates a `ILIKE` query against all of the model's string-like columns.
46+
47+
{attr}`.ModelManager.search_provider` can be reassigned to any callable that
48+
takes a `value` argument and returns a list of
49+
{class}`magql.search.SearchResult` instances.

docs/search.md

Lines changed: 0 additions & 2 deletions
This file was deleted.

docs/start.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ a model. Let's look at what it created for the `Task` model:
125125
It also provides two global queries:
126126

127127
* `search` takes a value and searches all string columns in all models. A UI
128-
could use this to provide a global search bar. See {doc}`search`.
128+
could use this to provide a global search bar. See {doc}`q-search`.
129129
* `check_delete(type, id)` takes a model name and row id and checks what would
130-
be affected if the row was deleted. See {doc}`check_delete`.
130+
be affected if the row was deleted. See {doc}`q-check_delete`.
131131

132132

133133
Customizing the Schema

0 commit comments

Comments
 (0)