RDFLib store using SQLAlchemy dbapi as back-end
Branch: develop
Clone or download
adamhadani Merge pull request #28 from RDFLib/feature/ah-mysql-connectiojns
Call engine.dispose() before setting to None in close()
Latest commit abe2088 Jan 24, 2017
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
rdflib_sqlalchemy
test fix flake8-print issues Nov 22, 2016
.bumpversion.cfg bump version Nov 23, 2016
.gitignore
.travis.yml drop python 2.7 from test matrix, more cleanup Nov 16, 2016
CONTRIBUTORS.md
MANIFEST.in
README.md
setup.cfg
setup.py
tox.ini

README.md

RDFLib-SQLAlchemy

A SQLAlchemy-backed, formula-aware RDFLib Store. It stores its triples in the following partitions:

  • Asserted non rdf:type statements.
  • Asserted rdf:type statements (in a table which models Class membership). The motivation for this partition is primarily query speed and scalability as most graphs will always have more rdf:type statements than others.
  • All Quoted statements.

In addition, it persists namespace mappings in a separate table.

Back-end persistence

Back-end persistence is provided by SQLAlchemy.

Tested dialects are:

  • SQLite, using the built-in Python driver or, for Python 2.5, pysqlite
  • MySQL, using the MySQLdb-python driver or, for Python 3, mysql-connector
  • PostgreSQL, using the psycopg2 driver or the pg8000 driver.

pysqlite: https://pypi.python.org/pypi/pysqlite

MySQLdb-python: https://pypi.python.org/pypi/MySQL-python

mysql-connector: http://dev.mysql.com/doc/connector-python/en/connector-python.html

psycopg2: https://pypi.python.org/pypi/psycopg2

pg8000: https://pypi.python.org/pypi/pg8000

Development

Github repository: https://github.com/RDFLib/rdflib-sqlalchemy

Continuous integration: https://travis-ci.org/RDFLib/rdflib-sqlalchemy/

Travis CI PyPI PyPI PyPI

PyPI PyPI PyPI PyPI

An illustrative unit test:

    import unittest
    from rdflib import plugin, Graph, Literal, URIRef
    from rdflib.store import Store


    class SQLASQLiteGraphTestCase(unittest.TestCase):
        ident = URIRef("rdflib_test")
        uri = Literal("sqlite://")

        def setUp(self):
            store = plugin.get("SQLAlchemy", Store)(identifier=self.ident)
            self.graph = Graph(store, identifier=self.ident)
            self.graph.open(self.uri, create=True)

        def tearDown(self):
            self.graph.destroy(self.uri)
            try:
                self.graph.close()
            except:
                pass

        def test01(self):
            self.assert_(self.graph is not None)
            print(self.graph)

    if __name__ == '__main__':
        unittest.main()

Running the tests

This is slightly baroque because of the test matrix (PostgreSQL|MySQL|SQLite x Python2.5|2.6|2.7|3.2) ...

Using nose::

DB='pgsql' DBURI='postgresql+psycopg2://user:password@host/dbname' nosetests

Using tox::

DB='pgsql' DBURI='postgresql+psycopg2://user:password@host/dbname' tox -e py32

DB variants are 'pgsql', 'mysql' and 'sqlite'

Sample DBURI values::

dburi = Literal("mysql://username:password@hostname:port/database-name?other-parameter")
dburi = Literal("mysql+mysqldb://user:password@hostname:port/database?charset=utf8")
dburi = Literal('postgresql+psycopg2://user:pasword@hostname:port/database')
dburi = Literal('postgresql+pg8000://user:pasword@hostname:port/database')
dburi = Literal('sqlite:////absolute/path/to/foo.db')
dburi = Literal("sqlite:///%(here)s/development.sqlite" % {"here": os.getcwd()})
dburi = Literal('sqlite://') # In-memory