{ "info": { "author": "Charles Leifer", "author_email": "coleifer@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python" ], "description": "sqlite-schemaless\n=================\n\nSchemaless database built on top of SQLite. I based the design of `sqlite-schemaless` on the data-store described in [this Uber engineering post](https://eng.uber.com/schemaless-part-one/). All data is stored in a single SQLite database, which can either be on-disk or in-memory.\n\nData is organized by **KeySpace**. A KeySpace might be something like \"users\" or \"tweets\". Inside each KeySpace there are **Rows**. A row is identified by an integer `row_key` and consists of one or more named columns. In these columns you can store arbitrary JSON blobs. So:\n\n* KeySpace1:\n * Row1:\n * ColumnA: {arbitrary json data}\n * ColumnB: {more json data}\n * Row2:\n * ColumnA: {json data}\n * ColumnC: {json data}\n * Row3:\n * ColumnA: {json data}\n * ColumnB: {json data}\n\nSo far this is really not that interesting. Things get interesting, though, with the addition of **secondary indexes** and **event emitters**.\n\nSecondary Indexes\n-----------------\n\nYou can create indexes on values stored in the JSON column data. Suppose we are storing User data in the `user` column. This user data is structured roughly like this:\n\n```javascript\n{\n 'name': 'Charles',\n 'username': 'coleifer',\n 'location': {\n 'state': 'KS',\n 'city': 'Lawrence',\n }\n}\n```\n\nIf we wanted to search for users by username, we would create an index using JSON-path notation: `$.username`. If we wanted to search by the user's state, we would create an index on `$.location.state`.\n\nHere is how the code would look to set this up:\n\n```python\n\ndb = Schemaless(':memory:') # Create an in-memory database.\n\n# Indexes are initialized with the column name and JSON-path.\nusername_idx = Index('user', '$.username')\nstate_idx = Index('user', '$.location.state')\n\n# When we create a KeySpace, we can include a list of indexes:\nusers = db.keyspace('users', username_idx, state_idx)\n\n# To store a user, write:\ncharles = users.create_row(\n user={\n 'username': 'coleifer',\n 'location': {'city': 'Lawrence', 'state': 'KS'},\n },\n social=[\n {'name': 'github', 'username': 'coleifer'},\n {'name': 'twitter', 'username': 'coleifer'},\n ])\n\n# To query for users in Kansas, we can write:\nks_users = state_idx.query('KS')\nfor row in ks_users:\n print row['user']['username']\n```\n\nEvent emitters\n--------------\n\nThe other neat feature of `sqlite-schemaless` is the event emitter functionality. This feature allows you to bind handlers to execute code when a new row is created or updated. You can bind handlers to an individual keyspace, or to all keyspaces.\n\nFor example, let's add a simple handler to print usernames as they're added or updated.\n\n```python\n\n@users.handler\ndef print_username(row, column, value):\n if column == 'user':\n print value['username']\n```\n\nWhenever we add or update the `user` column of a row in the `users` KeySpace, the callback will fire and print the username.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/coleifer/sqlite-schemaless/", "keywords": null, "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "sqlite-schemaless", "package_url": "https://pypi.org/project/sqlite-schemaless/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/sqlite-schemaless/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/coleifer/sqlite-schemaless/" }, "release_url": "https://pypi.org/project/sqlite-schemaless/0.1.2/", "requires_dist": null, "requires_python": null, "summary": "schemaless database on top of sqlite", "version": "0.1.2" }, "last_serial": 2151270, "releases": { "0.1.2": [ { "comment_text": "", "digests": { "md5": "5c2d119ff13fa3eeec2a4c55742551dc", "sha256": "3a76805884a4aaff67c387fcf85ca384eed565e12fe098113ad44b3d4bbbf1f9" }, "downloads": -1, "filename": "sqlite-schemaless-0.1.2.tar.gz", "has_sig": false, "md5_digest": "5c2d119ff13fa3eeec2a4c55742551dc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6094, "upload_time": "2016-06-05T05:18:21", "url": "https://files.pythonhosted.org/packages/43/57/2a6a4f814097fa99681c068773bc9c3e63f574a982b0b361d989d2cc016d/sqlite-schemaless-0.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5c2d119ff13fa3eeec2a4c55742551dc", "sha256": "3a76805884a4aaff67c387fcf85ca384eed565e12fe098113ad44b3d4bbbf1f9" }, "downloads": -1, "filename": "sqlite-schemaless-0.1.2.tar.gz", "has_sig": false, "md5_digest": "5c2d119ff13fa3eeec2a4c55742551dc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6094, "upload_time": "2016-06-05T05:18:21", "url": "https://files.pythonhosted.org/packages/43/57/2a6a4f814097fa99681c068773bc9c3e63f574a982b0b361d989d2cc016d/sqlite-schemaless-0.1.2.tar.gz" } ] }