pydantic_sqlite


Namepydantic_sqlite JSON
Version 0.2.2 PyPI version JSON
download
home_pagehttps://github.com/Phil997/pydantic-sqlite
SummarySimple package for storing pydantic BaseModels in an in-memory SQLite database.
upload_time2024-04-05 21:31:16
maintainerNone
docs_urlNone
authorYour Name
requires_python<4.0.0,>=3.8.1
licenseMIT
keywords pydantic sqlite-utils sqlite3
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pydantic_sqlite
Simple package for storing pydantic BaseModels in an in-memory SQLite database.

## Installation

    pip install pydantic-sqlite

## Basic Example
Create two objects of the type TestCase and add them to the database in the table 'Test'. Later, all values in the table are printed while iteration over the Table 'Test'.

``` python
from pydantic_sqlite import DataBase
from pydantic import BaseModel
from uuid import uuid4

class TestCase(BaseModel):
    uuid: str
    name: str 
    age: int
        
test1 = TestCase(uuid=str(uuid4()), name="Bob", age=12)
test2 = TestCase(uuid=str(uuid4()), name="Alice", age=28)

db = DataBase()
db.add("Test", test1)
db.add("Test", test2)

for x in db("Test"):
    assert issubclass(x.__class__, BaseModel)
    assert isinstance(x, TestCase)
    print(x)

#>>> uuid='10d002bc-9941-4943-a46b-82b8214bf618' name='Bob' age=12
#>>> uuid='595fd605-4684-4f78-96a5-8420bdb3fc0f' name='Alice' age=28

```

## Nested Example
Create one object of the type address and two objects of the type person. Each person has an attribute of the type address. 
When adding the person to the database, the database needs the foreign_table 'Adresses' to create the foreign key. This means that when iterating over the table 'Persons', a complete object "Person" can be created again, which has an attribute of the type 'Address'.


```python
from pydantic_sqlite import DataBase
from pydantic import BaseModel
from uuid import uuid4

class Address(BaseModel):
    uuid: str
    town: str
    street: str
    number: int
        
class Person(BaseModel):
    uuid: str
    name: str 
    address: Address

address = Address(uuid=str(uuid4()), town="Berlin", street="Bahnhofstraße", number=67)
person1 = Person(uuid=str(uuid4()), name="Bob", address=address)
person2 = Person(uuid=str(uuid4()), name="Alice", address=address)

db = DataBase()
db.add("Adresses", address)
db.add("Persons", person1, foreign_tables={'address': 'Adresses'})
db.add("Persons", person2, foreign_tables={'address': 'Adresses'})

for x in db("Adresses"):
    assert issubclass(x.__class__, BaseModel)
    assert isinstance(x, Address)
    print(x)

for y in db("Persons"):
    assert issubclass(y.__class__, BaseModel)
    assert isinstance(y, Person)
    print(y)

#>>> uuid='7cd5410e-cfaa-481e-a201-ad04cd959719' town='Berlin' street='Bahnhofstraße' number=67
#>>> uuid='cc1cedaf-dac5-4fc2-a11a-41c6631271a5' name='Bob' address=Address(uuid='7cd5410e-cfaa-481e-a201-ad04cd959719', town='Berlin', street='Bahnhofstraße', number=67)
#>>> uuid='b144ed22-d8a4-46da-8a18-e34c260d7c45' name='Alice' address=Address(uuid='7cd5410e-cfaa-481e-a201-ad04cd959719', town='Berlin', street='Bahnhofstraße', number=67)

```

# Nested Example without foreign Table
If you do not want to have an additional table, you can save an object of the BaseModel type differently.

In this example, the address object is not saved as an additional table. It is stored as a string in a column of the table 'Persons'. To realise this, the class `SQConfig` is added to the Address class. This class must contain the method `convert`, which determines how the object is to be stored in SQLite. During the subsequent loading, an object of the type Address is created again from the string with the function pydantic.validator.

```python
from pydantic_sqlite import DataBase
from pydantic import BaseModel, validator
from uuid import uuid4

class Address(BaseModel):
    town: str
    street: str
        
    class SQConfig:
        special_insert: bool = True

        def convert(obj):
            return f"{obj.town},{obj.street}"

class Person(BaseModel):
    uuid: str
    name: str 
    address: Address
        
    @validator('address', pre=True)
    def validate(cls, v):
        if isinstance(v, Address):
            return v
        town, street = v.split(',')
        return Address(town=town, street=street)

address = Address(town="Berlin", street="Bahnhofstraße 67")
person1 = Person(uuid=str(uuid4()), name="Bob", address=address)
person2 = Person(uuid=str(uuid4()), name="Alice", address=address)

db = DataBase()
db.add("Persons", person1)
db.add("Persons", person2)

for y in db("Persons"):
    assert issubclass(y.__class__, BaseModel)
    assert isinstance(y, Person)
    print(y)

#>>> uuid='802f50d6-b6a2-47f4-bb96-4375790daed9' name='Bob' address=Address(town='Berlin', street='Bahnhofstraße 67')
#>>> uuid='79488c0d-44c8-4a6a-afa3-1ed0b88af4a2' name='Alice' address=Address(town='Berlin', street='Bahnhofstraße 67')
```

# DB_Handler
The DB_handler provides a wrapper for the DataBase. The database returned by the context manager can be used in the same way as in the previous examples. 

However, the handler has the advantage that if an exception occurs, e.g. a 'ZeroDevisionError', a database with the last values is saved as '<<dbname_crash>>.db'. If this file already exists, the file name is incremented.

This example creates two files hello.db and hello_crash.db If you run this script twice, three files are created: hello.db, hello_crash.db and hello_crash_(1).db
```python
from pydantic_sqlite import DataBase, DB_Handler
from pydantic import BaseModel, validator
from uuid import uuid4

class TestCase(BaseModel):
    uuid: str
    name: str 
    age: int

with DB_Handler("hello") as db:
    test1 = TestCase(uuid=str(uuid4()), name="Bob", age=12)
    db.add("Test", test1)
    for x in db("Test"):
        assert issubclass(x.__class__, BaseModel)
        assert isinstance(x, TestCase)
        print(x)
    db.save("hello_world.db")
    
    1/0

#>>> uuid='04d6dfad-0ce5-4222-8686-22348e1f0c0b' name='Bob' age=12
#>>> ---------------------------------------------------------------------------
#>>> ZeroDivisionError    Traceback (most recent call last)
#>>> ~\AppData\Local\Temp/ipykernel_20124/1430346317.py in <module>
#>>>      17     db.save("hello_world.db")
#>>>      18 
#>>> ---> 19     1/0
#>>> 
#>>> ZeroDivisionError: division by zero
```
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Phil997/pydantic-sqlite",
    "name": "pydantic_sqlite",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0.0,>=3.8.1",
    "maintainer_email": null,
    "keywords": "pydantic, sqlite-utils, sqlite3",
    "author": "Your Name",
    "author_email": "you@example.com",
    "download_url": "https://files.pythonhosted.org/packages/90/36/cf76f6043147b38a803b717e9d7ffdc17ec07a7f1c57f84df3ad7b713462/pydantic_sqlite-0.2.2.tar.gz",
    "platform": null,
    "description": "# pydantic_sqlite\nSimple package for storing pydantic BaseModels in an in-memory SQLite database.\n\n## Installation\n\n    pip install pydantic-sqlite\n\n## Basic Example\nCreate two objects of the type TestCase and add them to the database in the table 'Test'. Later, all values in the table are printed while iteration over the Table 'Test'.\n\n``` python\nfrom pydantic_sqlite import DataBase\nfrom pydantic import BaseModel\nfrom uuid import uuid4\n\nclass TestCase(BaseModel):\n    uuid: str\n    name: str \n    age: int\n        \ntest1 = TestCase(uuid=str(uuid4()), name=\"Bob\", age=12)\ntest2 = TestCase(uuid=str(uuid4()), name=\"Alice\", age=28)\n\ndb = DataBase()\ndb.add(\"Test\", test1)\ndb.add(\"Test\", test2)\n\nfor x in db(\"Test\"):\n    assert issubclass(x.__class__, BaseModel)\n    assert isinstance(x, TestCase)\n    print(x)\n\n#>>> uuid='10d002bc-9941-4943-a46b-82b8214bf618' name='Bob' age=12\n#>>> uuid='595fd605-4684-4f78-96a5-8420bdb3fc0f' name='Alice' age=28\n\n```\n\n## Nested Example\nCreate one object of the type address and two objects of the type person. Each person has an attribute of the type address. \nWhen adding the person to the database, the database needs the foreign_table 'Adresses' to create the foreign key. This means that when iterating over the table 'Persons', a complete object \"Person\" can be created again, which has an attribute of the type 'Address'.\n\n\n```python\nfrom pydantic_sqlite import DataBase\nfrom pydantic import BaseModel\nfrom uuid import uuid4\n\nclass Address(BaseModel):\n    uuid: str\n    town: str\n    street: str\n    number: int\n        \nclass Person(BaseModel):\n    uuid: str\n    name: str \n    address: Address\n\naddress = Address(uuid=str(uuid4()), town=\"Berlin\", street=\"Bahnhofstra\u00dfe\", number=67)\nperson1 = Person(uuid=str(uuid4()), name=\"Bob\", address=address)\nperson2 = Person(uuid=str(uuid4()), name=\"Alice\", address=address)\n\ndb = DataBase()\ndb.add(\"Adresses\", address)\ndb.add(\"Persons\", person1, foreign_tables={'address': 'Adresses'})\ndb.add(\"Persons\", person2, foreign_tables={'address': 'Adresses'})\n\nfor x in db(\"Adresses\"):\n    assert issubclass(x.__class__, BaseModel)\n    assert isinstance(x, Address)\n    print(x)\n\nfor y in db(\"Persons\"):\n    assert issubclass(y.__class__, BaseModel)\n    assert isinstance(y, Person)\n    print(y)\n\n#>>> uuid='7cd5410e-cfaa-481e-a201-ad04cd959719' town='Berlin' street='Bahnhofstra\u00dfe' number=67\n#>>> uuid='cc1cedaf-dac5-4fc2-a11a-41c6631271a5' name='Bob' address=Address(uuid='7cd5410e-cfaa-481e-a201-ad04cd959719', town='Berlin', street='Bahnhofstra\u00dfe', number=67)\n#>>> uuid='b144ed22-d8a4-46da-8a18-e34c260d7c45' name='Alice' address=Address(uuid='7cd5410e-cfaa-481e-a201-ad04cd959719', town='Berlin', street='Bahnhofstra\u00dfe', number=67)\n\n```\n\n# Nested Example without foreign Table\nIf you do not want to have an additional table, you can save an object of the BaseModel type differently.\n\nIn this example, the address object is not saved as an additional table. It is stored as a string in a column of the table 'Persons'. To realise this, the class `SQConfig` is added to the Address class. This class must contain the method `convert`, which determines how the object is to be stored in SQLite. During the subsequent loading, an object of the type Address is created again from the string with the function pydantic.validator.\n\n```python\nfrom pydantic_sqlite import DataBase\nfrom pydantic import BaseModel, validator\nfrom uuid import uuid4\n\nclass Address(BaseModel):\n    town: str\n    street: str\n        \n    class SQConfig:\n        special_insert: bool = True\n\n        def convert(obj):\n            return f\"{obj.town},{obj.street}\"\n\nclass Person(BaseModel):\n    uuid: str\n    name: str \n    address: Address\n        \n    @validator('address', pre=True)\n    def validate(cls, v):\n        if isinstance(v, Address):\n            return v\n        town, street = v.split(',')\n        return Address(town=town, street=street)\n\naddress = Address(town=\"Berlin\", street=\"Bahnhofstra\u00dfe 67\")\nperson1 = Person(uuid=str(uuid4()), name=\"Bob\", address=address)\nperson2 = Person(uuid=str(uuid4()), name=\"Alice\", address=address)\n\ndb = DataBase()\ndb.add(\"Persons\", person1)\ndb.add(\"Persons\", person2)\n\nfor y in db(\"Persons\"):\n    assert issubclass(y.__class__, BaseModel)\n    assert isinstance(y, Person)\n    print(y)\n\n#>>> uuid='802f50d6-b6a2-47f4-bb96-4375790daed9' name='Bob' address=Address(town='Berlin', street='Bahnhofstra\u00dfe 67')\n#>>> uuid='79488c0d-44c8-4a6a-afa3-1ed0b88af4a2' name='Alice' address=Address(town='Berlin', street='Bahnhofstra\u00dfe 67')\n```\n\n# DB_Handler\nThe DB_handler provides a wrapper for the DataBase. The database returned by the context manager can be used in the same way as in the previous examples. \n\nHowever, the handler has the advantage that if an exception occurs, e.g. a 'ZeroDevisionError', a database with the last values is saved as '<<dbname_crash>>.db'. If this file already exists, the file name is incremented.\n\nThis example creates two files hello.db and hello_crash.db If you run this script twice, three files are created: hello.db, hello_crash.db and hello_crash_(1).db\n```python\nfrom pydantic_sqlite import DataBase, DB_Handler\nfrom pydantic import BaseModel, validator\nfrom uuid import uuid4\n\nclass TestCase(BaseModel):\n    uuid: str\n    name: str \n    age: int\n\nwith DB_Handler(\"hello\") as db:\n    test1 = TestCase(uuid=str(uuid4()), name=\"Bob\", age=12)\n    db.add(\"Test\", test1)\n    for x in db(\"Test\"):\n        assert issubclass(x.__class__, BaseModel)\n        assert isinstance(x, TestCase)\n        print(x)\n    db.save(\"hello_world.db\")\n    \n    1/0\n\n#>>> uuid='04d6dfad-0ce5-4222-8686-22348e1f0c0b' name='Bob' age=12\n#>>> ---------------------------------------------------------------------------\n#>>> ZeroDivisionError    Traceback (most recent call last)\n#>>> ~\\AppData\\Local\\Temp/ipykernel_20124/1430346317.py in <module>\n#>>>      17     db.save(\"hello_world.db\")\n#>>>      18 \n#>>> ---> 19     1/0\n#>>> \n#>>> ZeroDivisionError: division by zero\n```",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Simple package for storing pydantic BaseModels in an in-memory SQLite database.",
    "version": "0.2.2",
    "project_urls": {
        "Homepage": "https://github.com/Phil997/pydantic-sqlite",
        "Repository": "https://github.com/Phil997/pydantic-sqlite"
    },
    "split_keywords": [
        "pydantic",
        " sqlite-utils",
        " sqlite3"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6dd50ca626a69e6555a5055ab70dc35e10850aeb7198e1f20cd86178b6ebd085",
                "md5": "8d1d0ca694c0992568692df2178c9f7c",
                "sha256": "155ce35c8fc55b947126077ec31ef8d86fd177380566760ba0e6db74fdc5f0e9"
            },
            "downloads": -1,
            "filename": "pydantic_sqlite-0.2.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8d1d0ca694c0992568692df2178c9f7c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0.0,>=3.8.1",
            "size": 9200,
            "upload_time": "2024-04-05T21:31:14",
            "upload_time_iso_8601": "2024-04-05T21:31:14.686086Z",
            "url": "https://files.pythonhosted.org/packages/6d/d5/0ca626a69e6555a5055ab70dc35e10850aeb7198e1f20cd86178b6ebd085/pydantic_sqlite-0.2.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9036cf76f6043147b38a803b717e9d7ffdc17ec07a7f1c57f84df3ad7b713462",
                "md5": "fb336dbe607e9fafafbb62d00a6c233b",
                "sha256": "18dc214673e2c41466511ebcdc6e76689648686b0db10c97e5ada7550045df91"
            },
            "downloads": -1,
            "filename": "pydantic_sqlite-0.2.2.tar.gz",
            "has_sig": false,
            "md5_digest": "fb336dbe607e9fafafbb62d00a6c233b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0.0,>=3.8.1",
            "size": 7342,
            "upload_time": "2024-04-05T21:31:16",
            "upload_time_iso_8601": "2024-04-05T21:31:16.249496Z",
            "url": "https://files.pythonhosted.org/packages/90/36/cf76f6043147b38a803b717e9d7ffdc17ec07a7f1c57f84df3ad7b713462/pydantic_sqlite-0.2.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-05 21:31:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Phil997",
    "github_project": "pydantic-sqlite",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "pydantic_sqlite"
}
        
Elapsed time: 0.68725s