Update docs
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,11 +1,11 @@
|
||||
.idea/*
|
||||
aiodatalite/__pycache__/*
|
||||
*.pyc
|
||||
datalite/*.db
|
||||
aiodatalite/*.db
|
||||
*.db
|
||||
docs/_build/*
|
||||
build/*
|
||||
datalite.egg-info/*
|
||||
aiodatalite.egg-info/*
|
||||
dist/*
|
||||
venv/*
|
||||
t/
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
@@ -1,39 +1,39 @@
|
||||
API Reference
|
||||
================
|
||||
|
||||
datalite Module
|
||||
aiodatalite Module
|
||||
-----------------------------------
|
||||
|
||||
.. autodecorator:: datalite.datalite
|
||||
.. autodecorator:: aiodatalite.datalite
|
||||
|
||||
datalite.constraints module
|
||||
aiodatalite.constraints module
|
||||
----------------------------------
|
||||
|
||||
.. automodule:: datalite.constraints
|
||||
.. automodule:: aiodatalite.constraints
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
datalite.fetch module
|
||||
aiodatalite.fetch module
|
||||
---------------------
|
||||
|
||||
.. automodule:: datalite.fetch
|
||||
.. automodule:: aiodatalite.fetch
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
datalite.mass_actions module
|
||||
aiodatalite.mass_actions module
|
||||
------------------------------
|
||||
|
||||
.. automodule:: datalite.mass_actions
|
||||
.. automodule:: aiodatalite.mass_actions
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
datalite.migrations module
|
||||
aiodatalite.migrations module
|
||||
----------------------------
|
||||
|
||||
.. automodule:: datalite.migrations
|
||||
.. automodule:: aiodatalite.migrations
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -19,7 +19,7 @@ sys.path.insert(0, os.path.abspath("../."))
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = "Datalite"
|
||||
project = "aiodatalite"
|
||||
copyright = "2020, Ege Ozkan; 2024, hhh"
|
||||
author = "Ege Ozkan, hhh"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ specific column **MUST** abide by specific constraints, these might be
|
||||
* Values of this column can be used to identify a record. (``PRIMARY``)
|
||||
* Values of this column has a default value. (``DEFAULT``)
|
||||
|
||||
Some of these constraints are already implemented in datalite. With all of the set,
|
||||
Some of these constraints are already implemented in aiodatalite. With all of the set,
|
||||
is planned to be implemented in the future.
|
||||
|
||||
Default Values
|
||||
@@ -53,7 +53,7 @@ Uniqueness constraint is declared thusly:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datalite.constraints import Unique
|
||||
from aiodatalite.constraints import Unique
|
||||
|
||||
@datalite("db.db")
|
||||
@dataclass
|
||||
|
||||
@@ -4,14 +4,14 @@ Basic Decorator Operations
|
||||
Creating a datalite class
|
||||
-------------------------
|
||||
|
||||
A datalite class is a special dataclass. It is created by using a decorator ``@datalite.datalite``,
|
||||
A datalite class is a special dataclass. It is created by using a decorator ``@aiodatalite.datalite``,
|
||||
members of this class are, from Python's perspective, just normal classes. However, they have
|
||||
additional methods and attributes. ``@datalite`` decorator needs a database path to be provided.
|
||||
This database is the database the table for the dataclass will be created.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datalite import datalite
|
||||
from aiodatalite import datalite
|
||||
@datalite(db_path='db.db')
|
||||
@dataclass
|
||||
class Student:
|
||||
@@ -29,6 +29,18 @@ Special Methods
|
||||
Each object initialised from a dataclass decorated with the ``@dataclass`` decorator automatically
|
||||
gains access to three special methods. It should be noted, due to the nature of the library, extensions
|
||||
such as ``mypy`` and IDEs such as PyCharm will not be able to see these methods and may raise exceptions.
|
||||
So, aiodatalite introduces ``typed`` module and ``DataliteHinted`` class, from which you can inherit your dataclass.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiodatalite import datalite
|
||||
from aiodatalite.typed import DataliteHinted
|
||||
@datalite(db_path='db.db')
|
||||
@dataclass
|
||||
class Student(DataliteHinted):
|
||||
student_id: int = 1
|
||||
student_name: str = "Kurt Gödel"
|
||||
student_gpa: float = 3.9
|
||||
|
||||
With this in mind, let us create a new object and run the methods over this objects.
|
||||
|
||||
@@ -36,6 +48,31 @@ With this in mind, let us create a new object and run the methods over this obje
|
||||
|
||||
new_student = Student(0, "Albert Einstein", 4.0)
|
||||
|
||||
Marking up Table
|
||||
#################
|
||||
Due to the limitations of asynchronous programming, we cannot automatically create the table asynchronously,
|
||||
so we provide two ways to do this.
|
||||
|
||||
First way is to create the table automatically in !synchronous! mode by explicitly passing an argument to the decorator.
|
||||
We don't know what consequences this can lead to specifically in your application, but if you are confident in yourself,
|
||||
use this method
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
...
|
||||
@datalite(db_path='db.db', automarkup=True)
|
||||
@dataclass
|
||||
class Student(DataliteHinted):
|
||||
...
|
||||
|
||||
The second way, which may be less convenient when using some frameworks but is more controllable, is to call the
|
||||
asynchronous ``create_table`` method, which will be added to your dataclass after using ``@datalite`` decorator,
|
||||
alongside with some other methods.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
await new_student.markup_table()
|
||||
|
||||
Creating an Entry
|
||||
##################
|
||||
|
||||
@@ -46,7 +83,7 @@ in the table:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
new_student.create_entry()
|
||||
await new_student.create_entry()
|
||||
|
||||
This also modifies the object in an intresting way, it adds a new attribute ``obj_id``, this is a unique,
|
||||
autoincremented value in the database. It can be accessed by ``new_student.obj_id``.
|
||||
@@ -60,7 +97,7 @@ record in the database, this method must be called.
|
||||
.. code-block:: python
|
||||
|
||||
new_student.student_gpa = 5.0 # He is Einstein, after all.
|
||||
new_student.update_entry()
|
||||
await new_student.update_entry()
|
||||
|
||||
|
||||
Deleting an Entry
|
||||
@@ -71,9 +108,57 @@ be used.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
new_student.remove_entry()
|
||||
await new_student.remove_entry()
|
||||
|
||||
.. warning::
|
||||
|
||||
It should be noted that, if the ``new_student.obj_id`` attribute is modified, ``.update_entry()``
|
||||
and ``.remove_entry()`` may have unexpected results.
|
||||
|
||||
|
||||
Tweaked Types
|
||||
--------------
|
||||
Sometimes your objects may be somewhat complex or use a nested structure. This fork allows nesting by using the pickle
|
||||
module, which gives you the ability to turn your objects into pure bytes that can be written to and from the database.
|
||||
When the ``tweaked`` parameter is enabled, data that can be written natively is written as is, and data that cannot be
|
||||
written in this way is first processed by pickle.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiodatalite import datalite
|
||||
from aiodatalite.typed import DataliteHinted
|
||||
|
||||
# Bag dataclass defined somewhere
|
||||
|
||||
@datalite(db_path='db.db')
|
||||
@dataclass
|
||||
class Student(DataliteHinted):
|
||||
student_id: int = 1
|
||||
student_name: str = "Kurt Gödel"
|
||||
student_gpa: float = 3.9
|
||||
bag: Bag = Bag(
|
||||
size="big",
|
||||
items_number=88,
|
||||
...
|
||||
)
|
||||
|
||||
But with great opportunity comes great responsibility, so using nested models can lead to difficulties in migrating data
|
||||
and updating the structure of nested objects, so changing the ``Bag`` object in this example, in theory, can break the
|
||||
database without the possibility of migration. We recommend using multiple tables and simple relationships between them
|
||||
(must be organized independently) in such cases.
|
||||
|
||||
The tweaked functionality of types can be disabled by passing the tweaked parameter as False to the datalite decorator
|
||||
.. code-block:: python
|
||||
|
||||
from aiodatalite import datalite
|
||||
from aiodatalite.typed import DataliteHinted
|
||||
|
||||
# Bag is defined somewhere as datalite table instance
|
||||
|
||||
@datalite(db_path='db.db', tweaked=False)
|
||||
@dataclass
|
||||
class Student(DataliteHinted):
|
||||
bag_id: int
|
||||
student_id: int = 1
|
||||
student_name: str = "Kurt Gödel"
|
||||
student_gpa: float = 3.9
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
Fetching Functions
|
||||
===================
|
||||
|
||||
A database is hardly useful if data does not persist between program runs. In ``datalite``
|
||||
one can use ``datalite.fetch`` module to fetch data back from the database.
|
||||
A database is hardly useful if data does not persist between program runs. In ``aiodatalite``
|
||||
one can use ``aiodatalite.fetch`` module to fetch data back from the database.
|
||||
|
||||
There are different sorts of fetching. One can fetch all the objects of a class
|
||||
using ``fetch_all(class_)``, or an object with a specific object id using ``fetch_from(class_, obj_id)``.
|
||||
using ``await fetch_all(class_)``, or an object with a specific object id using ``await fetch_from(class_, obj_id)``
|
||||
(useful when you know object id inside database, but lost the reference to the object itself somewhere).
|
||||
There are more functions for plural conditional fetching (``fetch_if``, ``fetch_where``) where
|
||||
all objects fitting a condition will be returned, as well as singular conditional fetching that returns
|
||||
the first object that fits a condition (``fetch_equals``).
|
||||
@@ -13,7 +14,7 @@ the first object that fits a condition (``fetch_equals``).
|
||||
Pagination
|
||||
##########
|
||||
|
||||
Pagination is a feature that allows a portion of the results to be returned. Since ``datalite``
|
||||
Pagination is a feature that allows a portion of the results to be returned. Since ``aiodatalite``
|
||||
is built to work with databases that may include large amounts of data, many systems using large
|
||||
portions of data also make use of pagination. By building pagination inside the system, we hope to
|
||||
allow easier usage.
|
||||
@@ -29,4 +30,4 @@ each page has. When ``page`` is set to 0, all results are returned irregardless
|
||||
|
||||
.. important::
|
||||
|
||||
More information regarding the ``datalite.fetch`` functions can be found in the API reference.
|
||||
More information regarding the ``aiodatalite.fetch`` functions can be found in the API reference.
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
.. Datalite documentation master file, created by
|
||||
sphinx-quickstart on Thu Aug 13 21:01:34 2020.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
|
||||
Welcome to Datalite's documentation!
|
||||
Welcome to aioatalite's documentation!
|
||||
====================================
|
||||
|
||||
Datalite is a simple to use Python library that can bind a dataclass to an
|
||||
aioatalite is a simple to use async Python library that can bind a dataclass to an
|
||||
sqlite3 database.
|
||||
|
||||
|
||||
@@ -22,7 +16,7 @@ Documentation
|
||||
constraints
|
||||
fetch
|
||||
migration
|
||||
datalite
|
||||
aiodatalite
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
Getting Started
|
||||
=================
|
||||
|
||||
Welcome to the documentation of datalite. Datalite provides a simple, intuitive way to bind dataclasses
|
||||
to sqlite3 databases. In its current version, it provides implicit support for conversion between
|
||||
``int``, ``float``, ``str``, ``bytes`` classes and their ``sqlite3`` counterparts, default values,
|
||||
Welcome to the documentation of aiodatalite, an asynchronous fork of datalite. Datalite provides a simple, intuitive
|
||||
way to bind dataclasses to sqlite3 databases. In its current version, it provides implicit support for conversion
|
||||
between ``int``, ``float``, ``str``, ``bytes`` classes and their ``sqlite3`` counterparts, default values,
|
||||
basic schema migration and fetching functions.
|
||||
Also, aiodatalite introduces ``tweaked`` parameter (True by default), which allows using pickle to store any values
|
||||
in database
|
||||
|
||||
Installation
|
||||
############
|
||||
@@ -13,11 +15,11 @@ Simply write:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install datalite
|
||||
pip install aiodatalite
|
||||
|
||||
In the shell. And then, whenever you want to use it in Python, you can use:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import datalite
|
||||
import aiodatalite
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
@@ -1,8 +1,8 @@
|
||||
Schema Migrations
|
||||
==================
|
||||
|
||||
Datalite provides a module, ``datalite.migrations`` that handles schema migrations. When a class
|
||||
definition is modified, ``datalite.migrations.basic_migration`` can be called to automatically
|
||||
Datalite provides a module, ``aiodatalite.migrations`` that handles schema migrations. When a class
|
||||
definition is modified, ``aiodatalite.migrations.migrate`` can be called to
|
||||
transfer records to a table fitting the new definitions.
|
||||
|
||||
Let us say we have made changes to the fields of a dataclass called ``Student`` and now,
|
||||
@@ -13,7 +13,34 @@ name change. We can achieve this easily by:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
datalite.basic_migration(Student, {'studentt_id': 'student_id'})
|
||||
await migrate(Student, {'studentt_id': 'student_id'})
|
||||
|
||||
This will make all the changes, if we had not provided the second argument,
|
||||
the values would be lost.
|
||||
|
||||
Also, ``migrate`` provides automatic backup before migration, you can turn it off by passing ``do_backup=False`` into
|
||||
function.
|
||||
|
||||
We also introduce safe migration defaults. This parameter should be passed a key-value dictionary, where the key is the
|
||||
name of the new required field, and the value is what should be written to the old records in the database.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiodatalite import datalite
|
||||
from aiodatalite.typed import DataliteHinted
|
||||
@datalite(db_path='db.db')
|
||||
@dataclass
|
||||
class Student(DataliteHinted):
|
||||
new_obligatory_field: str # the database will break if not all records have this field
|
||||
student_id: int = 1
|
||||
student_name: str = "Kurt Gödel"
|
||||
student_gpa: float = 3.9
|
||||
|
||||
So in this situation basically what you need to do is:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
await migrate(Student, safe_migration_defaults={
|
||||
"new_obligatory_field": "some value for records that already exist in the database"
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user