renames etc.

This commit is contained in:
collerek
2020-08-14 19:36:50 +02:00
parent 0ebecc8610
commit 062d35168f
50 changed files with 398 additions and 299 deletions

View File

@ -199,7 +199,7 @@ But you can overwrite this name by providing `related_name` parameter like below
Since related models are coming from Relationship Manager the reverse relation on access returns list of `wekref.proxy` to avoid circular references.
!!!info
All relations are stored in lists, but when you access parent `Model` the ORM is unpacking the value for you.
All relations are stored in lists, but when you access parent `Model` the ormar is unpacking the value for you.
Read more in [relations][relations].
[relations]: ./relations.md

View File

@ -1,4 +1,4 @@
# Async-ORM
# ORMar
<p>
<a href="https://travis-ci.com/collerek/async-orm">
@ -15,42 +15,42 @@
</a>
</p>
The `async-orm` package is an async ORM for Python, with support for Postgres,
MySQL, and SQLite. ORM is built with:
The `ormar` package is an async ORM for Python, with support for Postgres,
MySQL, and SQLite. Ormar is built with:
* [`SQLAlchemy core`][sqlalchemy-core] for query building.
* [`databases`][databases] for cross-database async support.
* [`pydantic`][pydantic] for data validation.
Because ORM is built on SQLAlchemy core, you can use [`alembic`][alembic] to provide
Because ormar is built on SQLAlchemy core, you can use [`alembic`][alembic] to provide
database migrations.
The goal was to create a simple orm that can be used directly with [`fastapi`][fastapi] that bases it's data validation on pydantic.
The goal was to create a simple ORM that can be used directly with [`fastapi`][fastapi] that bases it's data validation on pydantic.
Initial work was inspired by [`encode/orm`][encode/orm].
The encode package was too simple (i.e. no ability to join two times to the same table) and used typesystem for data checks.
**async-orm is still under development:** We recommend pinning any dependencies with `aorm~=0.0.1`
**ormar is still under development:** We recommend pinning any dependencies with `ormar~=0.0.1`
**Note**: Use `ipython` to try this from the console, since it supports `await`.
```python
import databases
import orm
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Note(orm.Model):
class Note(ormar.Model):
__tablename__ = "notes"
__database__ = database
__metadata__ = metadata
# primary keys of type int by dafault are set to autoincrement
id = orm.Integer(primary_key=True)
text = orm.String(length=100)
completed = orm.Boolean(default=False)
id = ormar.Integer(primary_key=True)
text = ormar.String(length=100)
completed = ormar.Boolean(default=False)
# Create the database
engine = sqlalchemy.create_engine(str(database.url))
@ -84,35 +84,35 @@ note = await Note.objects.get(pk=2)
note.pk # 2
```
ORM supports loading and filtering across foreign keys...
Ormar supports loading and filtering across foreign keys...
```python
import databases
import orm
import ormar
import sqlalchemy
database = databases.Database("sqlite:///db.sqlite")
metadata = sqlalchemy.MetaData()
class Album(orm.Model):
class Album(ormar.Model):
__tablename__ = "album"
__metadata__ = metadata
__database__ = database
id = orm.Integer(primary_key=True)
name = orm.String(length=100)
id = ormar.Integer(primary_key=True)
name = ormar.String(length=100)
class Track(orm.Model):
class Track(ormar.Model):
__tablename__ = "track"
__metadata__ = metadata
__database__ = database
id = orm.Integer(primary_key=True)
album = orm.ForeignKey(Album)
title = orm.String(length=100)
position = orm.Integer()
id = ormar.Integer(primary_key=True)
album = ormar.ForeignKey(Album)
title = ormar.String(length=100)
position = ormar.Integer()
# Create some records to work with.
@ -187,17 +187,17 @@ All fields are required unless one of the following is set:
### Fields Types
* `orm.String(length)`
* `orm.Text()`
* `orm.Boolean()`
* `orm.Integer()`
* `orm.Float()`
* `orm.Date()`
* `orm.Time()`
* `orm.DateTime()`
* `orm.JSON()`
* `orm.BigInteger()`
* `orm.Decimal(lenght, precision)`
* `String(length)`
* `Text()`
* `Boolean()`
* `Integer()`
* `Float()`
* `Date()`
* `Time()`
* `DateTime()`
* `JSON()`
* `BigInteger()`
* `Decimal(lenght, precision)`
[sqlalchemy-core]: https://docs.sqlalchemy.org/en/latest/core/
[databases]: https://github.com/encode/databases

View File

@ -1,17 +1,20 @@
# Models
## Defining models
By defining an orm Model you get corresponding **Pydantic model** as well as **Sqlalchemy table** for free.
By defining an ormar Model you get corresponding **Pydantic model** as well as **Sqlalchemy table** for free.
They are being managed in the background and you do not have to create them on your own.
### Model Class
To build an ORM model you simply need to inherit a `orm.Model` class.
To build an ormar model you simply need to inherit a `ormar.Model` class.
```Python hl_lines="10"
--8<-- "../docs_src/models/docs001.py"
```
### Defining Fields
Next assign one or more of the [Fields][fields] as a class level variables.
Each table **has to** have a primary key column, which you specify by setting `primary_key=True` on selected field.
@ -31,17 +34,18 @@ By default if you assign primary key to `Integer` field, the `autoincrement` opt
You can disable by passing `autoincremant=False`.
```Python
id = orm.Integer(primary_key=True, autoincrement=False)
id = ormar.Integer(primary_key=True, autoincrement=False)
```
Names of the fields will be used for both the underlying `pydantic` model and `sqlalchemy` table.
### Dependencies
Since orm depends on [`databases`][databases] and [`sqlalchemy-core`][sqlalchemy-core] for database connection
Since ormar depends on [`databases`][databases] and [`sqlalchemy-core`][sqlalchemy-core] for database connection
and table creation you need to assign each `Model` with two special parameters.
#### Databases
One is `Database` instance created with your database url in [sqlalchemy connection string][sqlalchemy connection string] format.
Created instance needs to be passed to every `Model` with `__database__` parameter.
@ -55,6 +59,7 @@ Created instance needs to be passed to every `Model` with `__database__` paramet
You can create several ones if you want to use multiple databases.
#### Sqlalchemy
Second dependency is sqlalchemy `MetaData` instance.
Created instance needs to be passed to every `Model` with `__metadata__` parameter.
@ -123,6 +128,7 @@ The fields and relations are not stored on the `Model` itself
Apart from special parameters defined in the `Model` during definition (tablename, metadata etc.) the `Model` provides you with useful internals.
### Pydantic Model
To access auto created pydantic model you can use `Model.__pydantic_model__` parameter
For example to list model fields you can:
@ -138,6 +144,7 @@ For example to list model fields you can:
For more options visit official [pydantic][pydantic] documentation.
### Sqlalchemy Table
To access auto created sqlalchemy table you can use `Model.__table__` parameter
For example to list table columns you can:
@ -153,7 +160,8 @@ For example to list table columns you can:
For more options visit official [sqlalchemy-metadata][sqlalchemy-metadata] documentation.
### Fields Definition
To access orm `Fields` you can use `Model.__model_fields__` parameter
To access ormar `Fields` you can use `Model.__model_fields__` parameter
For example to list table model fields you can:

View File

@ -30,7 +30,7 @@ await malibu.save()
### load()
By default when you query a table without prefetching related models, the orm will still construct
By default when you query a table without prefetching related models, the ormar will still construct
your related models, but populate them only with the pk value.
```python

View File

@ -74,7 +74,7 @@ classes = await SchoolClass.objects.select_related(
Since you join two times to the same table (categories) it won't work by default -> you would need to use aliases for category tables and columns.
But don't worry - orm can handle situations like this, as it uses the Relationship Manager which has it's aliases defined for all relationships.
But don't worry - ormar can handle situations like this, as it uses the Relationship Manager which has it's aliases defined for all relationships.
Each class is registered with the same instance of the RelationshipManager that you can access like this:
@ -110,7 +110,7 @@ print(Teacher._orm_relationship_manager.resolve_relation_join(
### Query automatic construction
Orm is using those aliases during queries to both construct a meaningful and valid sql,
Ormar is using those aliases during queries to both construct a meaningful and valid sql,
as well as later use it to extract proper columns for proper nested models.
Running a previously mentioned query to select school classes and related teachers and students: