Skip to content

Commit

Permalink
Various (#38)
Browse files Browse the repository at this point in the history
* Add create_indexes_for_multiple_databases
* Add drop_indexes_for_multiple_databases
* Release 0.9.0
  • Loading branch information
tarsil authored Jun 12, 2024
1 parent 1d8cfab commit e66a9ab
Show file tree
Hide file tree
Showing 58 changed files with 1,678 additions and 216 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ jobs:
run: pip install hatch
- name: "Build package"
run: "hatch run build_with_check"
- name: "Build docs"
run: "hatch run docs:build"
- name: "Publish to PyPI"
run: "scripts/publish"
env:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ on:
push:
branches:
- "**"
paths-ignore:
- "docs/**"
pull_request:
branches: ["main"]
paths-ignore:
- "docs/**"
schedule:
- cron: "0 0 * * *"

Expand Down
37 changes: 28 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
.vscode/
# folders
*.egg-info/
.hypothesis/
.idea/
*.pyc
test.db
.coverage
.pytest_cache/
.mypy_cache/
.pytest_cache/
.scannerwork/
.tox/
.venv/
.vscode/
__pycache__/
*.egg-info/
htmlcov/
venv/
.idea/
virtualenv/
build/
dist/
node_modules/
results/
site/
site_lang/
target/

# files
**/*.so
**/*.sqlite
*.iml
**/*_test*
.DS_Store
.coverage
.coverage.*
.python-version
coverage.*
example.sqlite
File renamed without changes.
89 changes: 75 additions & 14 deletions docs/documents.md → docs/en/docs/documents.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ As you are probably aware, MongoDB is a NoSQL database, which means it doesn't h
This also means that with documents and NoSQL, **there are no joins and foreign keys**.

**Mongoz** implements those documents in a more friendly interface if you are still familiar with
ORMs or even if you use something like [Mongoz][edgy]. No reason to overcomplicate, right?
ORMs or even if you use something like [Edgy][edgy]. No reason to overcomplicate, right?

## Declaring documents

Expand All @@ -19,14 +19,14 @@ an instance of `Registry` from Mongoz.
There are more parameters you can use and pass into the document such as [tablename](#metaclass) and
a few more but more on this in this document.

Since **Mongoz** took inspiration from the interface of [Mongoz][edgy], that also means that a [Meta](#the-meta-class)
Since **Mongoz** took inspiration from the interface of [Edgy][edgy], that also means that a [Meta](#the-meta-class)
class should be declared.

Although this looks very simple, in fact **Mongoz** is doing a lot of work for you behind the
scenes.

```python
{!> ../docs_src/documents/declaring_models.py !}
{!> ../../../docs_src/documents/declaring_models.py !}
```

### Embedded Documents
Expand Down Expand Up @@ -73,7 +73,7 @@ approaches.
#### In a nutshell

```python
{!> ../docs_src/documents/registry/nutshell.py !}
{!> ../../../docs_src/documents/registry/nutshell.py !}
```

As you can see, when declaring the `registry` and assigning it to `registry`, that same `registry` is
Expand All @@ -84,7 +84,7 @@ then used in the `Meta` of the document.
Yes, you can also use the document inheritance to help you out with your documents and avoid repetition.

```python
{!> ../docs_src/documents/registry/inheritance_no_repeat.py !}
{!> ../../../docs_src/documents/registry/inheritance_no_repeat.py !}
```

As you can see, the `User` and `Product` tables are inheriting from the `BaseDocument` where the
Expand All @@ -103,7 +103,7 @@ What if your class is abstract? Can you inherit the registry anyway?
Of course! That doesn't change anything with the registry.

```python
{!> ../docs_src/documents/registry/inheritance_abstract.py !}
{!> ../../../docs_src/documents/registry/inheritance_abstract.py !}
```

### Table name
Expand All @@ -114,7 +114,7 @@ if a `collection` field in the `Meta` object is not declared, it will pluralise
#### Document without table name

```python
{!> ../docs_src/documents/tablename/model_no_tablename.py !}
{!> ../../../docs_src/documents/tablename/model_no_tablename.py !}
```

As mentioned in the example, because a `collection` was not declared, **Mongoz** will pluralise
Expand All @@ -123,14 +123,14 @@ the python class name `User` and it will become `users` in your database.
#### Document with a table name

```python
{!> ../docs_src/documents/tablename/model_with_tablename.py !}
{!> ../../../docs_src/documents/tablename/model_with_tablename.py !}
```

Here the `collection` is being explicitly declared as `users`. Although it matches with a
puralisation of the python class name, this could also be something else.

```python
{!> ../docs_src/documents/tablename/model_diff_tn.py !}
{!> ../../../docs_src/documents/tablename/model_diff_tn.py !}
```

In this example, the `User` class will be represented by a `db_users` mapping into the database.
Expand Down Expand Up @@ -159,7 +159,7 @@ In this document we already mentioned abstract documents and how to use them but
examples to be even clear.

```python
{!> ../docs_src/documents/abstract/simple.py !}
{!> ../../../docs_src/documents/abstract/simple.py !}
```

This document itself does not do much alone. This simply creates a `BaseDocument` and declares the
Expand All @@ -173,7 +173,7 @@ case for these to be use in the first place.
Let us see a more complex example and how to use it.

```python
{!> ../docs_src/documents/abstract/common.py !}
{!> ../../../docs_src/documents/abstract/common.py !}
```

This is already quite a complex example where `User` and `Product` have both common functionality
Expand Down Expand Up @@ -233,19 +233,19 @@ The simplest and cleanest way of declaring an index with **Mongoz**. You declare
the document field.

```python hl_lines="11"
{!> ../docs_src/documents/indexes/simple.py !}
{!> ../../../docs_src/documents/indexes/simple.py !}
```

#### Index via Meta

```python hl_lines="17"
{!> ../docs_src/documents/indexes/simple2.py !}
{!> ../../../docs_src/documents/indexes/simple2.py !}
```

#### Complex indexes

```python hl_lines="9 17-20"
{!> ../docs_src/documents/indexes/complex_together.py !}
{!> ../../../docs_src/documents/indexes/complex_together.py !}
```

### Index Operations
Expand Down Expand Up @@ -338,4 +338,65 @@ await User.drop_index("name")
If you try to drop an index with a field name not declared in the document or not declared
as Index, at least, a `InvalidKeyError` is raised.

#### Document checks

If you also want to make sure that you run the proper checks for the indexes, for example, an index was dropped
from the document and you want to make sure that is reflected, you can also do it.

The syntax is very clear ans simple:

```python
await MyDocument.check_indexes()
```

For example:

```python
await User.check_indexes()
```

This can be useful if you want to make sure that for every [registry](./registry.md), all the documents have the
indexes checked before hand.

[Read more](./registry.md#run-some-document-checks) about that in that section.


#### Create indexes for multiple databases

What if you have the same document in multiple databases (multi tenancy, for example) and you would like to reflect the
indexes in all of them? Mongoz comes with that option as well.

The database names must be passed as a list or tuple of strings.

The syntax is as simlpe as this:

```python
await MyDocument.create_indexes_for_multiple_databases(["db_one", "db_two", "db_three"])
```

For example:

```python
await User.create_indexes_for_multiple_databases(["db_one", "db_two", "db_three"])
```

#### Drop indexes for multiple databases

What if you have the same document in multiple databases (multi tenancy, for example) and you would like to drop the
indexes in all of them? Mongoz comes with that option as well.

The database names must be passed as a list or tuple of strings.

The syntax is as simlpe as this:

```python
await MyDocument.drop_indexes_for_multiple_databases(["db_one", "db_two", "db_three"])
```

For example:

```python
await User.drop_indexes_for_multiple_databases(["db_one", "db_two", "db_three"])
```

[edgy]: https://edgy.tarsild.io
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ To define an `EmbeddedDocument` you should inherit from `mongoz.EmbeddedDocument
[fields](./fields.md) in the way you would define for any other `mongoz.Document`.

```python hl_lines="4 10 14-15 19 23 28 30-31"
{!> ../docs_src/documents/embed.py !}
{!> ../../../docs_src/documents/embed.py !}
```

As you can see, the `EmbeddedDocument` is not a standlone document itself but part of the
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 4 additions & 4 deletions docs/managers.md → docs/en/docs/managers.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ allow you to build unique tailored queries ready to be used by your documents.
Let us see an example.

```python
{!> ../docs_src/managers/simple.py !}
{!> ../../../docs_src/managers/simple.py !}
```

When querying the `User` table, the `objects` (manager) is the default and **should** be always
Expand All @@ -28,13 +28,13 @@ For those familiar with Django managers, the principle is exactly the same. 😀
**The managers must be type annotated ClassVar** or an error be raised.

```python
{!> ../docs_src/managers/example.py !}
{!> ../../../docs_src/managers/example.py !}
```

Let us now create new manager and use it with our previous example.

```python
{!> ../docs_src/managers/custom.py !}
{!> ../../../docs_src/managers/custom.py !}
```

These managers can be as complex as you like with as many filters as you desire. What you need is
Expand All @@ -46,7 +46,7 @@ Overriding the default manager is also possible by creating the custom manager a
the `objects` manager.

```python
{!> ../docs_src/managers/override.py !}
{!> ../../../docs_src/managers/override.py !}
```

!!! Warning
Expand Down
2 changes: 1 addition & 1 deletion docs/mongoz.md → docs/en/docs/mongoz.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ The following is an example how to start with Mongoz and more details and exampl
Use `ipython` to run the following from the console, since it supports `await`.

```python
{!> ../docs_src/quickstart/quickstart.py !}
{!> ../../../docs_src/quickstart/quickstart.py !}
```

Now you can generate some documents and insert them into the database.
Expand Down
4 changes: 2 additions & 2 deletions docs/queries.md → docs/en/docs/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Let us get familar with queries.
Let us assume you have the following `User` document defined.

```python
{!> ../docs_src/queries/document.py !}
{!> ../../../docs_src/queries/document.py !}
```

As mentioned before, Mongoz allows to use two ways of querying. Via `manager` and via `queryset`.
Expand Down Expand Up @@ -991,7 +991,7 @@ Querying [embedded documents](./embedded-documents.md) is also easy and here the
Let us see an example.

```python hl_lines="17"
{!> ../docs_src/queries/embed.py !}
{!> ../../../docs_src/queries/embed.py !}
```

We can now create some instances of the `User`.
Expand Down
58 changes: 58 additions & 0 deletions docs/en/docs/registry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Registry

When using the **Mongoz**, you must use the **Registry** object to tell exactly where the
database is going to be.

Imagine the registry as a mapping between your documents and the database where is going to be written.

And is just that, nothing else and very simple but effective object.

The registry is also the object that you might want to use when generating migrations using
Alembic.

```python hl_lines="19"
{!> ../../../docs_src/registry/model.py !}
```

## Parameters

* **url** - The database URL to connect to.

```python
from mongoz import Registry

registry = Registry(url="mongodb://localhost:27017")
```

## Custom registry

Can you have your own custom Registry? Yes, of course! You simply need to subclass the `Registry`
class and continue from there like any other python class.

```python
{!> ../../../docs_src/registry/custom_registry.py !}
```

## Run some document checks

Sometimes you might want to make sure that all the documents have the indexes up to date beforehand. This
can be particularly useful if you already have a document and some indexes or were updated, added or removed. This
functionality runs those checks for all the documents of the given registry.

```python
{!> ../../../docs_src/registry/document_checks.py !}
```

### Using within a framework

This functionality can be useful to be also plugged if you use, for example, an ASGI Framework such as Starlette,
[Lilya](https://lilya.dev) or [Esmerald](https://esmerald.dev).

These frameworks handle the event lifecycle for you and this is where you want to make sure these checks are run beforehand.

Since Mongoz is from the same team as [Lilya](https://lilya.dev) and [Esmerald](https://esmerald.dev), let us see how it
would look like with Esmerald.

```python
{!> ../../../docs_src/registry/asgi_fw.py !}
```
16 changes: 16 additions & 0 deletions docs/release-notes.md → docs/en/docs/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Release Notes

## 0.9.0

### Added

- `create_indexes_for_multiple_databases` allowing to iterate for each document
the creating of the indexes in multiple databases.
- [Registry document checks](./registry.md#run-some-document-checks) allowing to check beforehand all the
index changes in a document.
- [Model check indexes](./documents.md#document-checks) to do the same checks for the indexes but for each document.
- [create_indexes_for_multiple_databases](./documents.md#create-indexes-for-multiple-databases).
- [drop_indexes_for_multiple_databases](./documents.md#drop-indexes-for-multiple-databases).

### Changed

- Cleaned up logic to design indexes in the `metaclass`.

## 0.8.0

### Changed
Expand Down
Loading

0 comments on commit e66a9ab

Please sign in to comment.