Skip to content

mattdood/graph-ein

Repository files navigation

Gif of Ein from Cowboy Bebop in space

Note: I do not make any claims to the Cowboy Bebop assets, names, or trademarks.

Graph-Ein

A graph database implemented in SQLite. This is great for creating a standalone, single file graph database.

Badge for GitHub issues. Badge for GitHub forks. Badge for GitHub stars. Badge for GitHub license, MIT. Badge for sharable Twitter link. Pytest PyPI version

Installation

To install the project, run the following:

pip install ein-graph

Usage

The project generates a database file if one is not provided. The database itself is accessible; however, the Graph object is the typical interface that should be used for interacting with the data stored.

Database

SQLite database files are created for each separate database path that is provided. These are utilized upon instantiation of the Graph object, which will discover each of the data objects stored in the file.

The database can be connected to via DBeaver or some other database client if you'd like to explore the data.

Note: For users that want to utilize additional SQLite features there are methods for executing arbitrary statements/multiple statements.

Schemas

Databases have a concept of "schemas" that are used to organize disparate nodes and edges from each other. As such, a schema is needed for each of the node/edge data points added.

Schemas are stored in table-form as follows:

<schema_name>_nodes
<schema_name>_edges

To look at these in action use the following on your database using a database client:

-- from "select-schemas.sql"
SELECT
    name
FROM
    sqlite_master
WHERE
    type = 'table'
    AND
    tbl_name LIKE '%' || ? || '%'
;

Note: The above should only be used after a setup has been performed to create a client and add a schema.

Graph

The Graph instantiates with all current data in the supplied path.

Graphs operate with "schemas" that help to logically separate different sub-graphs. These graphs can be connected via Edge objects to bridge clusters of nodes.

Any data added/updated/deleted via the Graph is also reflected at the database level at time of execution.

from ein.graph import Graph


graph = Graph(db_path="test.db")
graph.add_schema("some_schema")

Nodes

Each Node object is a representation of data stored in the database, all data should be capable of being rendered to JSON.

from ein.node import Node


node = Node(
    schema_name="some_schema",
    id="my-id",
    body={
        "some-key": 1,
        "other-key": "data"
    },
)

Edges

The graph's Edges are a pair of nodes with a relationship. These contain the source and target nodes (and optionally properties for weights).

from ein.edge import Edge


edge = Edge(
    schema_name="some_schema",
    source=Node(...),
    target=Node(...),
)

To bridge Node objects between two schemas the schema_name= argument should be supplied. This will be the database schema that the edge is stored in, but the schemas of the source and target will be discovered from the Node objects.

from ein.edge import Edge


node_one = Node(
    schema_name="some_schema",
    ...,
)

node_two = Node(
    schema_name="some_other_schema",
    ...,
)

edge = Edge(
    schema_name=node_one.schema_name,
    source=node_one,
    target=node_two,
)

print(edge.source_schema_name) # some_schema
print(edge.target_schema_name) # some_other_schema

Releasing builds

To release builds for the project we use a combination of tagging and changes to setup.py.

For any releases to test.pypi.org use a change to the version="..." inside of setup.py. Once a PR is merged into the main project the test release will be updated.

Any prod releases to pypi.org require a tagged version number. This should be done locally by running the following:

git checkout master
git pull master
git tag v<version-number-here>
git push origin v<version-number-here>

Rollbacks of versions

To roll a version back we need to delete the tagged release from the prod PyPI, then delete the GitHub tag.

git tag -d v<version-number-here>
git push origin :v<version-number-here>