Write some documentation
This commit is contained in:
parent
444b81eda0
commit
6182603b41
41
README.rst
41
README.rst
|
@ -1,8 +1,8 @@
|
||||||
.. _header:
|
.. _header:
|
||||||
|
|
||||||
************************
|
*************
|
||||||
calibrestekje
|
calibrestekje
|
||||||
************************
|
*************
|
||||||
|
|
||||||
.. image:: https://img.shields.io/badge/license-GPL-brightgreen.svg
|
.. image:: https://img.shields.io/badge/license-GPL-brightgreen.svg
|
||||||
:target: LICENSE
|
:target: LICENSE
|
||||||
|
@ -26,9 +26,32 @@ calibrestekje
|
||||||
|
|
||||||
.. _introduction:
|
.. _introduction:
|
||||||
|
|
||||||
Calibre database bindings for prototyping your own library software!
|
Library prototyping based on Calibre
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
Calibrestekje is a Python library which provides a way to work with the
|
||||||
|
`Calibre`_ metadata database outside the context of the Calibre desktop and web
|
||||||
|
interfaces. A set of generated `SQLAlchemy`_ bindings (see `sqlacodegen`_ for
|
||||||
|
more) are provided which allow for the querying of an existing Calibre metadata
|
||||||
|
database (a file typically called ``metadata.db``). These bindings are more
|
||||||
|
fine grained than Calibres `database interface`_ and provide access to the
|
||||||
|
Database table layer.
|
||||||
|
|
||||||
|
The idea of a "stekje" (Dutch word meaning "little graft") in the context of
|
||||||
|
software came out of the discussions at `Relearn`_ around cutting, grafting,
|
||||||
|
remixing, re-using and misusing software for collective work.
|
||||||
|
|
||||||
|
This stekje can be understood as a low level building block for experimenting
|
||||||
|
with new ways of doing library software. One exciting part about a stekje is
|
||||||
|
that it is possible that new roots will appear. It is hoped that Calibrestekje
|
||||||
|
may help new library software take root.
|
||||||
|
|
||||||
|
.. _Calibre: https://calibre-ebook.com/
|
||||||
|
.. _SQLALchemy: https://docs.sqlalchemy.org/
|
||||||
|
.. _sqlacodegen: https://github.com/agronholm/sqlacodegen
|
||||||
|
.. _database interface: https://manual.calibre-ebook.com/db_api.html
|
||||||
|
.. _Relearn: http://relearn.be/2019/
|
||||||
|
|
||||||
.. _example:
|
.. _example:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
|
@ -36,7 +59,17 @@ Example
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# TODO
|
from calibrestekje import Book, Publisher, init_session
|
||||||
|
|
||||||
|
session = init_session("sqlite:///mymetadata.db")
|
||||||
|
|
||||||
|
publisher = (session.query(Publisher)
|
||||||
|
.filter(Publisher.name == "MIT Press").one())
|
||||||
|
|
||||||
|
books = (session.query(Book)
|
||||||
|
.filter(Book.publishers.contains(publisher)))
|
||||||
|
|
||||||
|
print(f"Books published by MIT Press: {books.count()}")
|
||||||
|
|
||||||
.. _documentation:
|
.. _documentation:
|
||||||
|
|
||||||
|
|
|
@ -5,4 +5,4 @@ html_theme = 'sphinx_rtd_theme'
|
||||||
master_doc = 'index'
|
master_doc = 'index'
|
||||||
project = 'calibrestekje'
|
project = 'calibrestekje'
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
extensions = ['sphinx.ext.autodoc', 'sphinx_autodoc_typehints']
|
extensions = ['sphinx.ext.autodoc']
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
.. _examples:
|
||||||
|
|
||||||
|
********
|
||||||
|
Examples
|
||||||
|
********
|
||||||
|
|
||||||
|
In order to work with Calibrestkje, you'll need to learn more about
|
||||||
|
`SQLAlchemy`_. SQLAlchemy is a Python "Object Relational Mapper", meaning that
|
||||||
|
it can help you write Python programs that interact with a database without
|
||||||
|
having to write raw database queries (that is often harder to do correctly).
|
||||||
|
The `querying`_ documentation is particularly useful. The following examples
|
||||||
|
are laid out in a "cookbook" style. Hopefully there is something useful in here
|
||||||
|
for you.
|
||||||
|
|
||||||
|
.. _SQLAlchemy: https://docs.sqlalchemy.org/en/13/
|
||||||
|
.. _querying: https://docs.sqlalchemy.org/en/13/orm/tutorial.html#querying
|
||||||
|
|
||||||
|
Working with the Calibre database
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
Calibrestkje works with the Calibre metadata database. This means, you need to
|
||||||
|
install `Calibre`_ first on your system. On my Debian operating system , that
|
||||||
|
means I would run:
|
||||||
|
|
||||||
|
.. _Calibre: https://calibre-ebook.com
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ sudo apt install -y calibre
|
||||||
|
|
||||||
|
And the first time I run Calibre, I would find that a metadata database has
|
||||||
|
been created in the ``/home/myuser/calibre/`` folder with the name
|
||||||
|
``metadata.db``. If you've been using Calibre for some time already, then
|
||||||
|
you'll probably already have this folder and database.
|
||||||
|
|
||||||
|
Sometimes it is useful to start from an empty metadata database and this can be
|
||||||
|
achieved by creating one with the ``calibredb`` command on the command-line. An
|
||||||
|
example of this would be:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ mkdir mytestcalibredb
|
||||||
|
$ calibredb restore_database --really-do-it --with-library mytestcalibredb
|
||||||
|
|
||||||
|
Unfortunately, there is no "create new database command" (AFAIK) and therefore
|
||||||
|
it is required to run this magical incantation that is hard to remember.
|
||||||
|
Afterwards, you'll have a new ``mytestcalibredb/metadata.db`` file which you
|
||||||
|
can start to work with.
|
||||||
|
|
||||||
|
Please see the :ref:`limitations` documentation for understanding what
|
||||||
|
Calibrestekje can't do right now.
|
||||||
|
|
||||||
|
Initialising a new session
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from calibrestkje import init_session
|
||||||
|
|
||||||
|
sqlite_url = "sqlite:///path_to_my_calibre_metadata.db"
|
||||||
|
session = init_session(sqlite_url)
|
||||||
|
|
||||||
|
All books without a publisher
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
(session.query(Book)
|
||||||
|
.filter(Book.publishers == None))
|
||||||
|
|
||||||
|
All books with multiple authors
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from sqlalchemy.sql.expression import func
|
||||||
|
|
||||||
|
(session.query(Book)
|
||||||
|
.join(Book.authors)
|
||||||
|
.group_by(Book)
|
||||||
|
.having(func.count(Author.id) > 1))
|
||||||
|
|
||||||
|
List of all tags that contain some pattern
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
(session.query(Tag)
|
||||||
|
.filter(Tag.name.contains("humanities")))
|
|
@ -0,0 +1,40 @@
|
||||||
|
.. _forking:
|
||||||
|
|
||||||
|
*******
|
||||||
|
Forking
|
||||||
|
*******
|
||||||
|
|
||||||
|
If you're not interested in maintaining compatibility with Calibre and would
|
||||||
|
like to embark on a new experimental library but do not want to have to
|
||||||
|
re-invent the database schema, you can get Calibrestekje to output
|
||||||
|
`SQLAlchemy`_ schemas definition based on Calibre but ones which you can change
|
||||||
|
yourself. This makes it possible to add new columns and tables to your new
|
||||||
|
database.
|
||||||
|
|
||||||
|
.. _SQLALchemy: https://docs.sqlalchemy.org/
|
||||||
|
|
||||||
|
To get started, you would run the following command.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ calibrestekje generate > mynewdb.py
|
||||||
|
|
||||||
|
From there, you can tell SQLAlchemy to create a new Sqlite database based on
|
||||||
|
this schema.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from mynewdb import Base
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
|
||||||
|
engine = create_engine('sqlite:///mynewdb.db')
|
||||||
|
|
||||||
|
Base.metadata.create_all(engine)
|
||||||
|
|
||||||
|
It is then possible to investigate your new database with `sqlitebrowser`_.
|
||||||
|
|
||||||
|
.. _sqlitebrowser: https://sqlitebrowser.org/
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
sqlitebrowser mynewdb.db
|
|
@ -6,6 +6,9 @@
|
||||||
:hidden:
|
:hidden:
|
||||||
|
|
||||||
install
|
install
|
||||||
|
examples
|
||||||
|
forking
|
||||||
|
limitations
|
||||||
upgrade
|
upgrade
|
||||||
contribute
|
contribute
|
||||||
changelog
|
changelog
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
.. _limitations:
|
||||||
|
|
||||||
|
***********
|
||||||
|
Limitations
|
||||||
|
***********
|
||||||
|
|
||||||
|
* Only read-only access to the ``metadata.db`` is available file right now.
|
||||||
|
There is some more technical work that needs wrangling before it becomes
|
||||||
|
possible to programmatically write new entries to a ``metadata.db`` that is
|
||||||
|
managed by Calibre.
|
||||||
|
|
||||||
|
* It is not possible to extend the Calibre database schema from within the
|
||||||
|
context of Calibrestekje right now. This means you can't easily add a new
|
||||||
|
column to the Book table. It is however possible to "fork" the Calibre
|
||||||
|
database schema and make your own. This involves more work and it is not
|
||||||
|
clear if it is possible to stay compatible with the Calibre database schema
|
||||||
|
afterwards. This might be useful if you want to start from scratch but not
|
||||||
|
re-invent the database schema. See the :ref:`forking` documentation for more.
|
Loading…
Reference in New Issue