SQLiteFrame


NameSQLiteFrame JSON
Version 0.3.1 PyPI version JSON
download
home_page
SummaryA lightweight, zero-dependency ORM for SQLite in Python
upload_time2023-10-17 01:54:31
maintainer
docs_urlNone
author
requires_python>=3.8
licenseMIT License Copyright (c) 2023 Kieran Lock Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords orm sqlite3 schematics lightweight zero-dependency
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <a id="readme-top"></a> 



<!-- PROJECT SUMMARY -->
<br />
<div align="center">
  <img src="https://i.imgur.com/ryp9aJT.gif" alt="Logo">
  <br />
  
  <p align="center">
    A lightweight, zero-dependency ORM for SQLite in Python
    <br />
    <a href="https://sqliteframe-documentation.vercel.app/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="#about-the-project">About the Project</a>
    ·
    <a href="#getting-started">Getting Started</a>
    ·
    <a href="#basic-usage">Basic Usage</a>
    ·
    <a href="https://sqliteframe-documentation.vercel.app/">Documentation</a>
    ·
    <a href="https://github.com/Kieran-Lock/SQLiteFrame/blob/master/LICENSE">License</a>
  </p>
</div>



<!-- ABOUT THE PROJECT -->
## About the Project
SQLiteFrame is an SQLite ORM for python, designed to be as lightweight, intuitive, and simple to use as possible.  
It is designed to closely mimic SQL syntax whilst remaining as pythonic as possible to save developers valuable time _(and brain cells)_ when interacting with SQLite databases, by building reusable SQLite query objects using method-chaining, and abstracting away SQLite's connection and cursor system with a single context manager.

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- GETTING STARTED -->
## Getting Started

SQLiteFrame is available on [PyPI](https://pypi.org/project/SQLiteFrame). Simply install the package into your project environment with PIP:
```
pip install SQLiteFrame
```

To install specific previous versions, take a look at the [version history](https://github.com/Kieran-Lock/SQLiteFrame/releases), locate the version tag `(vX.Y.Z)`, and run:
```
pip install SQLiteFrame==X.Y.Z
```

SQLiteFrame has **ZERO** external dependencies - it uses only the standard library's `sqlite3` to execute SQLite commands.

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- BASIC USAGE EXAMPLES -->
## Basic Usage

### Creating a table
To create a table, use the template below. This will automatically run the CreateTable SQLite command for you:
```py
from sqliteframe import Database, table, String, Integer, Boolean
from pathlib import Path


database = Database(Path("<database_path>.db"), output=False)  # When the output parameter is True, the formed SQL query will be outputted into the console as a string every time a query is executed


@table(database)
class TableName:
    primary_key_field = String(primary_key=True)  # The primary key parameter is False by default
    second_column = Integer  # If only the default options are required, no brackets are necessary either
    third_column = Boolean(nullable=True)  # The nullable parameter is False by default
    fourth_column = String(default="This is a default value.")  # You can also opt-in to giving columns default values like this
```

### Managing Connections
Before you can interact with the tables you create, you must first connect to the database:
```py
with database.connection(commit=True)  # When the commit parameter is False, changes to the database will not be committed at the end of the context block
    ...  # Execute any statements while a connection is open
```

### Inserting Data
To insert data into an existing table, use the following query template:
```py
insert_statement = TableName.insert_into({
    TableName.primary_key_field: "PrimaryKey1",
    TableName.second_column: 1_000,
    TableName.third_column: True
})

with database.connection():
    insert_statement.execute()
```

### Fetching / Selecting Data
Fetching / selecting data from an existing table with pre-inserted data is done as below:
```py
select_statement = TableName.select(TableName.second_column, TableName.third_column)
with database.connection():
    select_statement.execute()
```

### Linking Tables (Foreign Keys)
Linking tables can be done with Foreign Keys in SQLiteFrame:
```py
from sqliteframe import Database, table, String, Integer, Boolean, ForeignKey
from pathlib import Path


database = Database(Path("<database_path>.db"), output=False)


@table(database)
class FirstTableName:
    primary_key_field = String(primary_key=True)
    second_column = Integer
    third_column = Boolean(nullable=True)


@table(database)
class SecondTableName:
    primary_key_field = Integer(primary_key=True)
    second_column = Boolean(nullable=True)
    third_column = String
    foreign_key_column = ForeignKey(FirstTableName)  # This column now references the primary key of the FirstTableName entity, and will infer its type
```

### Complex Data Fetching / Selection
To build more complex select queries, you can use `join`, `where`, and `order by`:
```py
from sqliteframe import JoinTypes, OrderTypes


select_statement = FirstTableName.select(SecondTableName.second_column, FirstTableName.third_column).join(
    SecondTableName, SecondTableName.foreign_key_column == FirstTableName.primary_key_field, join_type=JoinTypes.LEFT
).where(
    SecondTableName.third_column == "Criteria"
).order_by(
    FirstTableName.second_column, (OrderTypes.DESCENDING, OrderTypes.NULLS_FIRST)
)
with database.connection():
    select_statement.execute()
```

### Editing Data
To edit pre-inserted data, a `set` query can be used:
```py
set_statement = FirstTableName.set({
    TableName.second_column: 10_000,
    TableName.third_column: None  # This column is nullable, and so this is acceptable
}).where(
    (Person.primary_key_column == "PrimaryKey1") & (Person.second_column > 500)  # Brackets are ESSENTIAL with complex where clauses, as these statements use bitwise operators, which often have unexpected operator precedence
)
with database.connection():
    set_statement.execute()
```
_NOTE: The where clause can be emitted from this statement, but this would update **every** record in the target table._

### Deleting Data
To delete pre-inserted table data, use the `delete_from` query:
```py
delete_statement = TableName.delete_from().where(
    (TableName.second_column <= 250)
)
with database.connection():
    delete_statement.execute()
```
_NOTE: The where clause can be emitted from this statement, but this would delete **every** record in the target table._

### Dropping Tables
Dropping tables does not delete the table reference from python - just in the SQL. Tables which others tables depend on / reference cannot be deleted by default to maintain referential integrity. This behaviour can be changed when defining the referencing foreign key column.  
  
To entirely drop (delete) an existing table, use the `drop_table` statement:
```py
with database.connection():
    SecondTableName.drop_table().execute()  # This entity is dropped first as it depends on the FirstTableName entity
    FirstTableName.drop_table().execute()  # Cannot drop this entity until the SecondTableName entity is dropped
```

_For more examples and specific detail, please refer to the [Documentation](https://sqliteframe-documentation.vercel.app/)_

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- LICENSE -->
## License

Distributed under the MIT License. See [LICENSE](https://github.com/Kieran-Lock/SQLiteFrame/blob/master/LICENSE) for more information.

<p align="right">(<a href="#readme-top">back to top</a>)</p>

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "SQLiteFrame",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "orm,sqlite3,schematics,lightweight,zero-dependency",
    "author": "",
    "author_email": "Kieran Lock <kieran.lock@outlook.com>",
    "download_url": "https://files.pythonhosted.org/packages/5b/86/c4b4360258bf6d477ae79386ae184e382efde7ba05b42cbbe55fcedf22e0/SQLiteFrame-0.3.1.tar.gz",
    "platform": null,
    "description": "<a id=\"readme-top\"></a> \n\n\n\n<!-- PROJECT SUMMARY -->\n<br />\n<div align=\"center\">\n  <img src=\"https://i.imgur.com/ryp9aJT.gif\" alt=\"Logo\">\n  <br />\n  \n  <p align=\"center\">\n    A lightweight, zero-dependency ORM for SQLite in Python\n    <br />\n    <a href=\"https://sqliteframe-documentation.vercel.app/\"><strong>Explore the docs \u00bb</strong></a>\n    <br />\n    <br />\n    <a href=\"#about-the-project\">About the Project</a>\n    \u00b7\n    <a href=\"#getting-started\">Getting Started</a>\n    \u00b7\n    <a href=\"#basic-usage\">Basic Usage</a>\n    \u00b7\n    <a href=\"https://sqliteframe-documentation.vercel.app/\">Documentation</a>\n    \u00b7\n    <a href=\"https://github.com/Kieran-Lock/SQLiteFrame/blob/master/LICENSE\">License</a>\n  </p>\n</div>\n\n\n\n<!-- ABOUT THE PROJECT -->\n## About the Project\nSQLiteFrame is an SQLite ORM for python, designed to be as lightweight, intuitive, and simple to use as possible.  \nIt is designed to closely mimic SQL syntax whilst remaining as pythonic as possible to save developers valuable time _(and brain cells)_ when interacting with SQLite databases, by building reusable SQLite query objects using method-chaining, and abstracting away SQLite's connection and cursor system with a single context manager.\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n\n<!-- GETTING STARTED -->\n## Getting Started\n\nSQLiteFrame is available on [PyPI](https://pypi.org/project/SQLiteFrame). Simply install the package into your project environment with PIP:\n```\npip install SQLiteFrame\n```\n\nTo install specific previous versions, take a look at the [version history](https://github.com/Kieran-Lock/SQLiteFrame/releases), locate the version tag `(vX.Y.Z)`, and run:\n```\npip install SQLiteFrame==X.Y.Z\n```\n\nSQLiteFrame has **ZERO** external dependencies - it uses only the standard library's `sqlite3` to execute SQLite commands.\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n\n<!-- BASIC USAGE EXAMPLES -->\n## Basic Usage\n\n### Creating a table\nTo create a table, use the template below. This will automatically run the CreateTable SQLite command for you:\n```py\nfrom sqliteframe import Database, table, String, Integer, Boolean\nfrom pathlib import Path\n\n\ndatabase = Database(Path(\"<database_path>.db\"), output=False)  # When the output parameter is True, the formed SQL query will be outputted into the console as a string every time a query is executed\n\n\n@table(database)\nclass TableName:\n    primary_key_field = String(primary_key=True)  # The primary key parameter is False by default\n    second_column = Integer  # If only the default options are required, no brackets are necessary either\n    third_column = Boolean(nullable=True)  # The nullable parameter is False by default\n    fourth_column = String(default=\"This is a default value.\")  # You can also opt-in to giving columns default values like this\n```\n\n### Managing Connections\nBefore you can interact with the tables you create, you must first connect to the database:\n```py\nwith database.connection(commit=True)  # When the commit parameter is False, changes to the database will not be committed at the end of the context block\n    ...  # Execute any statements while a connection is open\n```\n\n### Inserting Data\nTo insert data into an existing table, use the following query template:\n```py\ninsert_statement = TableName.insert_into({\n    TableName.primary_key_field: \"PrimaryKey1\",\n    TableName.second_column: 1_000,\n    TableName.third_column: True\n})\n\nwith database.connection():\n    insert_statement.execute()\n```\n\n### Fetching / Selecting Data\nFetching / selecting data from an existing table with pre-inserted data is done as below:\n```py\nselect_statement = TableName.select(TableName.second_column, TableName.third_column)\nwith database.connection():\n    select_statement.execute()\n```\n\n### Linking Tables (Foreign Keys)\nLinking tables can be done with Foreign Keys in SQLiteFrame:\n```py\nfrom sqliteframe import Database, table, String, Integer, Boolean, ForeignKey\nfrom pathlib import Path\n\n\ndatabase = Database(Path(\"<database_path>.db\"), output=False)\n\n\n@table(database)\nclass FirstTableName:\n    primary_key_field = String(primary_key=True)\n    second_column = Integer\n    third_column = Boolean(nullable=True)\n\n\n@table(database)\nclass SecondTableName:\n    primary_key_field = Integer(primary_key=True)\n    second_column = Boolean(nullable=True)\n    third_column = String\n    foreign_key_column = ForeignKey(FirstTableName)  # This column now references the primary key of the FirstTableName entity, and will infer its type\n```\n\n### Complex Data Fetching / Selection\nTo build more complex select queries, you can use `join`, `where`, and `order by`:\n```py\nfrom sqliteframe import JoinTypes, OrderTypes\n\n\nselect_statement = FirstTableName.select(SecondTableName.second_column, FirstTableName.third_column).join(\n    SecondTableName, SecondTableName.foreign_key_column == FirstTableName.primary_key_field, join_type=JoinTypes.LEFT\n).where(\n    SecondTableName.third_column == \"Criteria\"\n).order_by(\n    FirstTableName.second_column, (OrderTypes.DESCENDING, OrderTypes.NULLS_FIRST)\n)\nwith database.connection():\n    select_statement.execute()\n```\n\n### Editing Data\nTo edit pre-inserted data, a `set` query can be used:\n```py\nset_statement = FirstTableName.set({\n    TableName.second_column: 10_000,\n    TableName.third_column: None  # This column is nullable, and so this is acceptable\n}).where(\n    (Person.primary_key_column == \"PrimaryKey1\") & (Person.second_column > 500)  # Brackets are ESSENTIAL with complex where clauses, as these statements use bitwise operators, which often have unexpected operator precedence\n)\nwith database.connection():\n    set_statement.execute()\n```\n_NOTE: The where clause can be emitted from this statement, but this would update **every** record in the target table._\n\n### Deleting Data\nTo delete pre-inserted table data, use the `delete_from` query:\n```py\ndelete_statement = TableName.delete_from().where(\n    (TableName.second_column <= 250)\n)\nwith database.connection():\n    delete_statement.execute()\n```\n_NOTE: The where clause can be emitted from this statement, but this would delete **every** record in the target table._\n\n### Dropping Tables\nDropping tables does not delete the table reference from python - just in the SQL. Tables which others tables depend on / reference cannot be deleted by default to maintain referential integrity. This behaviour can be changed when defining the referencing foreign key column.  \n  \nTo entirely drop (delete) an existing table, use the `drop_table` statement:\n```py\nwith database.connection():\n    SecondTableName.drop_table().execute()  # This entity is dropped first as it depends on the FirstTableName entity\n    FirstTableName.drop_table().execute()  # Cannot drop this entity until the SecondTableName entity is dropped\n```\n\n_For more examples and specific detail, please refer to the [Documentation](https://sqliteframe-documentation.vercel.app/)_\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n\n\n\n<!-- LICENSE -->\n## License\n\nDistributed under the MIT License. See [LICENSE](https://github.com/Kieran-Lock/SQLiteFrame/blob/master/LICENSE) for more information.\n\n<p align=\"right\">(<a href=\"#readme-top\">back to top</a>)</p>\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2023 Kieran Lock  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "A lightweight, zero-dependency ORM for SQLite in Python",
    "version": "0.3.1",
    "project_urls": {
        "Documentation": "https://sqliteframe-documentation.vercel.app/",
        "GitHub": "https://github.com/Kieran-Lock/SQLiteFrame",
        "License": "https://github.com/Kieran-Lock/SQLiteFrame/blob/master/LICENSE"
    },
    "split_keywords": [
        "orm",
        "sqlite3",
        "schematics",
        "lightweight",
        "zero-dependency"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "69dea81d1074f4e415c18f09baf89429d6269da0b22b99db9398ecbc1b4ff93f",
                "md5": "8102a7c1b363dc8aa1e1b2669241a82b",
                "sha256": "36427b4de682379c4c4d7bb9c0616af56394bc808ab00e7c699ee1cd3b6a0c00"
            },
            "downloads": -1,
            "filename": "SQLiteFrame-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8102a7c1b363dc8aa1e1b2669241a82b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 43083,
            "upload_time": "2023-10-17T01:54:29",
            "upload_time_iso_8601": "2023-10-17T01:54:29.893804Z",
            "url": "https://files.pythonhosted.org/packages/69/de/a81d1074f4e415c18f09baf89429d6269da0b22b99db9398ecbc1b4ff93f/SQLiteFrame-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5b86c4b4360258bf6d477ae79386ae184e382efde7ba05b42cbbe55fcedf22e0",
                "md5": "981cf46ef1ab2c04d7e4af935682e7d7",
                "sha256": "646abb6271a2fa86bb62fb1932afe6fb01373b09e8a8af4758d40a3e50bad48f"
            },
            "downloads": -1,
            "filename": "SQLiteFrame-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "981cf46ef1ab2c04d7e4af935682e7d7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 24090,
            "upload_time": "2023-10-17T01:54:31",
            "upload_time_iso_8601": "2023-10-17T01:54:31.332147Z",
            "url": "https://files.pythonhosted.org/packages/5b/86/c4b4360258bf6d477ae79386ae184e382efde7ba05b42cbbe55fcedf22e0/SQLiteFrame-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-17 01:54:31",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Kieran-Lock",
    "github_project": "SQLiteFrame",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "sqliteframe"
}
        
Elapsed time: 0.13269s