{ "info": { "author": "windymile.it", "author_email": "windymile.it@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6" ], "description": "# windyquery - A non-blocking Python PostgreSQL query builder\n\nWindyquery is a non-blocking PostgreSQL query builder with Asyncio.\n\n### Installation\n```\n$ pip install windyquery\n```\n\n### Connection\n```python\nimport asyncio\n\nfrom windyquery import DB, Schema\n\n# create DB connection for CRUD operatons\ndb = DB()\nasyncio.get_event_loop().run_until_complete(db.connect('db_name', {\n 'host': 'localhost',\n 'port': '5432',\n 'database': 'db_name',\n 'username': 'db_user_name',\n 'password': 'db_user_password'\n}, default=True))\n\n# create DB connection for migration operations\nschema = Schema()\nasyncio.get_event_loop().run_until_complete(schema.connect('db_name', {\n 'host': 'localhost',\n 'port': '5432',\n 'database': 'db_name',\n 'username': 'db_user_name',\n 'password': 'db_user_password'\n}, default=True, min_size=1, max_size=1))\n```\n\n### CRUD examples\n```python\n# SELECT\nresult = await db.table('users').select().first()\nresult['name']\n\n# INSERT\nawait db.table('users').insert(\n {'email': 'test1@example.com', 'password': 'my precious'},\n {'email': 'test2@example.com', 'password': 'my precious'}\n)\n\n# UPDATE\nawait db.table('users').where('id', 2).update({'name': 'new name'})\n\n# DELETE\nawait db.table('users').where('id', 2).delete()\n```\n\n### Migration examples\n```python\n# CREATE TABLE\nawait schema.create('users',\n schema.column('id').serial().primary_key(),\n schema.column('email').string().nullable(False).unique(),\n schema.column('password').string().nullable(False),\n schema.column('created_at').timestamp().nullable(False).default(\"NOW()\"),\n)\n\n# ADD TABLE COLUMN\nawait schema.table('users',\n schema.column('admin').boolean().nullable(False).default(False)\n)\n\n# DROP TABLE COLUMN\nawait schema.table('users',\n schema.column('admin').drop(),\n)\n\n# ADD INDEX\nawait schema.table('users',\n schema.index('email', 'created_at'),\n)\n\n# DROP INDEX\nawait schema.dropIndex('users_email_created_at_idx')\n```\n\n\n### JSONB examples\n```python\n# Create JSONB\nawait schema.create('users',\n schema.column('id').serial().primary_key(),\n schema.column('data').jsonb(),\n)\n\n# Insert JSONB\nawait db.table('users').insert(\n {'data': {'name': 'user1', 'address': {'city': 'Chicago', 'state': 'IL'}}},\n {'data': {'name': 'user2', 'address': {'city': 'New York', 'state': 'NY'}, 'admin': True}},\n)\n\n# SELECT JSONB\nuser = await db.table('users').select('data->name AS name', 'data->>name AS name_text', 'data->address AS address').where('id', 2).first() \n# row['name'] == '\"user2\"'\n# row['name_text'] == 'user2'\n# row['address'] == '{\"name\":\"user2\", \"address\":{\"city\":\"New York\", \"state\":\"NY\"}}'\n\n# UPDATE JSONB\nawait db.table('users').where('id', 2).update({'data': {'address': {'city': 'Richmond'}}})\nawait db.table('users').where('id', 2).update({'data->address->city': 'Richmond'})\n\n# JSONB in WHERE clause\nusers = await db.table('users').select('data->>name AS name').where(\"data->address->city\", 'Chicago')\n```\n\n### Raw sql examples\n```python\n# select_raw\nawait db.table('users').select_raw(\n 'ROUND(AVG(id),1) AS avg_id, COUNT(1) AS copies'\n).where('id', [4,5,6]).first()\n\n# insertRaw\ndb.table('users').insertRaw(\n '(\"id\", \"name\") SELECT $1, $2 WHERE NOT EXISTS (SELECT \"id\" FROM users WHERE \"id\" = $1)', [10, 'user name']\n))\n\n# raw\nawait db.raw('SELECT * FROM users WHERE id = $1', [2]).first()\n\n# use asyncpg (https://magicstack.github.io/asyncpg/current/usage.html)\nasync with db.conn_pools['db_name'].acquire() as connection:\n await connection.fetchrow('SELECT * FROM test')\n\n```\n\n### Model\nTo use Model, a **primary key** is required by the underneath table.\n```python\n# setup connection\nfrom windyquery import DB\nfrom windyquery.model import Event\n\nmodel_db = DB()\nasyncio.get_event_loop().run_until_complete(model_db.connect('db_name', {\n 'host': 'localhost',\n 'port': '5432',\n 'database': 'db_name',\n 'username': 'db_user_name',\n 'password': 'db_user_password'\n}, default=True))\nEvent.db.on_next(model_db)\n\n# a Model with default setup\nclass User(Model):\n pass\n# User.table == 'users'\n\n# more about naming convention\nclass AdminUser(Model):\n pass\n# AdminUser.table == 'admin_users'\n\n# override table name\nclass Custom(Model):\n table = 'my_custom'\n# Custom.table == 'my_custom'\n\n# find by id\nuser = await User.find(2)\n# user.id == 2\n\n# find mutiple\nusers = await User.find([1, 2])\n# users[1].id == 2\n\n# all\nall_users = await User.all()\n\n# find by where\nuser = await User.where(\"email\", 'test@example.com').first()\nusers = User.where(\"email\", 'test@example.com')\n\n# save a new record\nuser = User(email='test@example.com', password='password')\nuser = await user.save()\n\n# create a new record if not found\nuser = User.where('id', 10).where('name', 'not_such_name').first_or_new()\n\n# update existing record\nuser = await User.find(2)\nuser.name = 'new name'\nawait user.save()\n\n# JOSNB is converted to the matching python types (dict, list)\nuser = User.find(2)\nuser.data\n# {'data': {'name': 'user2', 'address': {'city': 'New York', 'state': 'NY'}}\nuser.data['address']['city'] = 'Richmond'\nawait user.save()\n```\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/bluerelay/windyquery", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "windyquery", "package_url": "https://pypi.org/project/windyquery/", "platform": "", "project_url": "https://pypi.org/project/windyquery/", "project_urls": { "Homepage": "https://github.com/bluerelay/windyquery" }, "release_url": "https://pypi.org/project/windyquery/0.0.2/", "requires_dist": [ "asyncpg", "rx" ], "requires_python": "", "summary": "A non-blocking PostgreSQL query builder using Asyncio", "version": "0.0.2" }, "last_serial": 4807292, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "3cb8f864e62ada6129fd1f50407f55e8", "sha256": "01e35461773aff34df808752c0a280b7fcd65ced2d002bf88e1cb6e0d034e96b" }, "downloads": -1, "filename": "windyquery-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "3cb8f864e62ada6129fd1f50407f55e8", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21398, "upload_time": "2019-02-11T01:50:27", "url": "https://files.pythonhosted.org/packages/b8/84/4f14fa7290e062940f1dd098c2d44c77fb5a4ac31b92693f4ca70db7139d/windyquery-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "82471cba679a8c01bb9b264a748df413", "sha256": "04a7b48033c061f13dd8757a416b52c995228872278f609d2abeabaaa254146f" }, "downloads": -1, "filename": "windyquery-0.0.1.tar.gz", "has_sig": false, "md5_digest": "82471cba679a8c01bb9b264a748df413", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14162, "upload_time": "2019-02-11T01:50:29", "url": "https://files.pythonhosted.org/packages/53/0a/e93b283d854615b13b34faf06675ea61b06734ad8c8c908a0dbbc069dc8d/windyquery-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "3f01b687c4d4e97ccf206f775a646e70", "sha256": "82719caef4339c3d8c200d7744b784a762f409198a22eabe20679380d6008f74" }, "downloads": -1, "filename": "windyquery-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "3f01b687c4d4e97ccf206f775a646e70", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22988, "upload_time": "2019-02-11T18:27:51", "url": "https://files.pythonhosted.org/packages/6d/1a/0d67aaa8d37daa96a5c9f7ecf897a56e2ec6ce9effd73eaa3dc75af502ec/windyquery-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b7af791e0bf43de3d40c6a217823afac", "sha256": "9449574bb801ba5d53a3f5c4f9928f85e76152b4df53dd58ddf25349879e8a28" }, "downloads": -1, "filename": "windyquery-0.0.2.tar.gz", "has_sig": false, "md5_digest": "b7af791e0bf43de3d40c6a217823afac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16163, "upload_time": "2019-02-11T18:27:52", "url": "https://files.pythonhosted.org/packages/4a/da/bc1fcbf53a1441cbadf2a075f5ab42c67d03bf224e8511d42018bfa885ed/windyquery-0.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3f01b687c4d4e97ccf206f775a646e70", "sha256": "82719caef4339c3d8c200d7744b784a762f409198a22eabe20679380d6008f74" }, "downloads": -1, "filename": "windyquery-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "3f01b687c4d4e97ccf206f775a646e70", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 22988, "upload_time": "2019-02-11T18:27:51", "url": "https://files.pythonhosted.org/packages/6d/1a/0d67aaa8d37daa96a5c9f7ecf897a56e2ec6ce9effd73eaa3dc75af502ec/windyquery-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b7af791e0bf43de3d40c6a217823afac", "sha256": "9449574bb801ba5d53a3f5c4f9928f85e76152b4df53dd58ddf25349879e8a28" }, "downloads": -1, "filename": "windyquery-0.0.2.tar.gz", "has_sig": false, "md5_digest": "b7af791e0bf43de3d40c6a217823afac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16163, "upload_time": "2019-02-11T18:27:52", "url": "https://files.pythonhosted.org/packages/4a/da/bc1fcbf53a1441cbadf2a075f5ab42c67d03bf224e8511d42018bfa885ed/windyquery-0.0.2.tar.gz" } ] }