{ "info": { "author": "Sam Beck", "author_email": "notsambeck@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# pandabase\n[![Build Status](https://travis-ci.org/notsambeck/pandabase.svg?branch=master)](https://travis-ci.org/notsambeck/pandabase)\n\npandabase links pandas DataFrames to SQL databases, supporting read, append, and upsert.\n\nBy default, uses DataFrame.index as the primary key. By using an explicit primary key, pandabase makes rational database schemas the obvious choice, and makes it easy to maintain clean data even when it must be updated frequently. \n\nDesigned for especially for time-series datasets that need to be updated over time and stored to disk, but are used primarily in-memory for computation.\n\nTested under Python 3.6 and 3.7, with new versions of Pandas (>= 0.24) SQLAlchemy (>= 1.3). Requires psycopg2 for postgres (8+) support.\n\nIt's a relatively new tool, but for my purposes it works great. Comments and contributions welcome.\n\n### Features\n* primary keys: by default, any named index is assumed to be the PK\n * also supports auto_index (with parameter auto_index=True)\n* insert modes: 'create_only', 'upsert', and 'append'\n* replaces pd.DataFrame.to_sql and pd.read_sql\n* tested under SQLite and PostgresQL\n* automated test suite in pytest\n * 93% test coverage\n* also includes pandabase.companda.companda(df1, df2) for rich comparisons of DataFrames\n\n### Design Considerations\n* Minimal dependencies: SQLAlchemy and Pandas are the only requirements\n* Database is the source of truth: will coerce incoming DataFrames to fit existing schema\n * but also is reasonably smart about how new tables are created from DataFrames\n* Not horrendously slow\n\n### License\nMIT license\n\n### Thanks\nCode partially stolen from Dataset and pandas.sql\n\n### Installation\nFrom your inside your virtual environment of choice:\n\n```bash\n~/$ pip install pandabase\n```\n\nFor latest version:\n\n```bash\n~/$ git clone https://github.com/notsambeck/pandabase\n~/$ cd pandabase\n~/pandabase/$ pip install -r requirements.txt\n~/pandabase/$ pip install .\n```\n\n### Usage\n```python\n# Python >= 3.6\n>>> import pandas as pd\n>>> import pandabase\n>>> my_data = pd.DataFrame(index=range(7, 12), \n columns=['some_number'],\n data=pd.np.random.random((5,1)))\n>>> my_data.index.name = 'made_up_name' # index must be named to use as PK\n>>> pandabase.to_sql(my_data, table_name='my_table', con='sqlite:///new_sqlite_db.sqlite', how='create_only')\nTable('my_table', ...\n>>> exit()\n```\n\nThat's all! \n\nYour data is now persistently stored in a SQLite database, using my_data.index as primary key. To append or update data, replace 'create_only' with 'append' or 'upsert'. To store records without an explicit index, use 'autoindex=True'.\n\n```bash\n~/pandabase$ ls\nnew_sqlite_db.sqlite\n```\n\n```python\n>>> import pandabase\n>>> df = pandabase.read_sql('my_table', con='sqlite:///new_sqlite_db.sqlite'))\n>>> df\n some_number \n7 0.722416 \n8 0.076045 \n9 0.213118 \n10 0.453716 \n11 0.406995\n```\n\n### Additional Features\nCompanda - rich comparisons of DataFrames. call companda on two DataFrames, get a Companda object back (that evaluates to True/False).\n\n```python\n>>> from pandabse.companda import companda\n>>> df = pandabase.read_sql('my_table', con='sqlite:///new_sqlite_db.sqlite'))\n>>> companda(df, df.copy())\nCompanda(True, message='Equal DataFrames')\n>>> bool(companda(df, df.copy()))\nTrue\n\n>>> df2 = df.copy\n>>> df2.iloc[1, 2] = -1000\n>>> companda(df, df2)\nCompanda(False, message='Columns, indices are equal, but unqual values in columns...')\n>>> bool(companda(df, df2))\nFalse\n```\n\nTable tools: pandabase. ...\n* add_columns_to_db(new_col, table_name, con):\n * \"\"\"Make new columns as needed with ALTER TABLE, as a weak substitute for migrations\"\"\"\n* drop_db_table(table_name, con):\n * \"\"\"Drop table [table_name] from con\"\"\"\n* get_db_table_names(con):\n * \"\"\"get a list of table names from database\"\"\"\n* get_table_column_names(con, table_name):\n * \"\"\"get a list of column names from database, table\"\"\"\n* describe_database(con):\n * \"\"\"get a description of database content: table_name: {table_info_dict}\"\"\"\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/notsambeck/pandabase", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "pandabase", "package_url": "https://pypi.org/project/pandabase/", "platform": "", "project_url": "https://pypi.org/project/pandabase/", "project_urls": { "Homepage": "https://github.com/notsambeck/pandabase" }, "release_url": "https://pypi.org/project/pandabase/0.2.1/", "requires_dist": [ "pandas (>=0.24.0)", "sqlalchemy (>=1.3.0)" ], "requires_python": "", "summary": "pandabase links pandas DataFrames to SQL databases. Upsert, append, read, drop, describe...", "version": "0.2.1" }, "last_serial": 5806762, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "bce945cb7433202b663d2977330b4ceb", "sha256": "0bac8b4f47d2c60835d9866eea4d759ff494292e1f29bdf27bc9e623d1be1b12" }, "downloads": -1, "filename": "pandabase-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "bce945cb7433202b663d2977330b4ceb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11453, "upload_time": "2019-08-12T00:14:55", "url": "https://files.pythonhosted.org/packages/3d/0f/f054480fea20fef416b38147dd628d84e59af39c81eefbf74bb74cfc416f/pandabase-0.1.1-py3-none-any.whl" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "24152057d1968994ef236046d9c2285f", "sha256": "f2634d36bb384198f90804b5ae89f798f36bea2a0c2bb524ad9bc707754f9a7d" }, "downloads": -1, "filename": "pandabase-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "24152057d1968994ef236046d9c2285f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12926, "upload_time": "2019-09-10T03:53:44", "url": "https://files.pythonhosted.org/packages/80/97/14dd35b2a5c8a153180361d344f34a1da379127704ddd46b7b0d50f2bbcb/pandabase-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "334d424f06b2db269d62b42c61d1cece", "sha256": "5be24f147f5e0d77df126227e1c10d94f9ba4a98298332a5a4219d6eed5da2e3" }, "downloads": -1, "filename": "pandabase-0.2.1.tar.gz", "has_sig": false, "md5_digest": "334d424f06b2db269d62b42c61d1cece", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12323, "upload_time": "2019-09-10T03:53:45", "url": "https://files.pythonhosted.org/packages/03/a9/7c4644d8a6d2cef4bc2093cdb01f279620ad80d2813311cadba4c0ba00c2/pandabase-0.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "24152057d1968994ef236046d9c2285f", "sha256": "f2634d36bb384198f90804b5ae89f798f36bea2a0c2bb524ad9bc707754f9a7d" }, "downloads": -1, "filename": "pandabase-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "24152057d1968994ef236046d9c2285f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12926, "upload_time": "2019-09-10T03:53:44", "url": "https://files.pythonhosted.org/packages/80/97/14dd35b2a5c8a153180361d344f34a1da379127704ddd46b7b0d50f2bbcb/pandabase-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "334d424f06b2db269d62b42c61d1cece", "sha256": "5be24f147f5e0d77df126227e1c10d94f9ba4a98298332a5a4219d6eed5da2e3" }, "downloads": -1, "filename": "pandabase-0.2.1.tar.gz", "has_sig": false, "md5_digest": "334d424f06b2db269d62b42c61d1cece", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12323, "upload_time": "2019-09-10T03:53:45", "url": "https://files.pythonhosted.org/packages/03/a9/7c4644d8a6d2cef4bc2093cdb01f279620ad80d2813311cadba4c0ba00c2/pandabase-0.2.1.tar.gz" } ] }