Skip to content

How to use EncryptedType of SQLAlchemy #447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
8 tasks done
ChuckMoe opened this issue Sep 12, 2022 · 0 comments
Open
8 tasks done

How to use EncryptedType of SQLAlchemy #447

ChuckMoe opened this issue Sep 12, 2022 · 0 comments
Labels
investigate question Further information is requested

Comments

@ChuckMoe
Copy link

ChuckMoe commented Sep 12, 2022

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the SQLModel documentation, with the integrated search.
  • I already searched in Google "How to X in SQLModel" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to SQLModel but to Pydantic.
  • I already checked if it is not related to SQLModel but to SQLAlchemy.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

import os
from typing import Optional

import sqlalchemy
from sqlalchemy import Column
from sqlalchemy_utils import EncryptedType
from sqlalchemy_utils.types.encrypted.encrypted_type import AesEngine
from sqlmodel import create_engine, Field, Session, SQLModel


# https://sqlalchemy-utils.readthedocs.io/en/latest/_modules/sqlalchemy_utils/types/encrypted/encrypted_type.html#EncryptedType
class Hero(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    # Because the secret name should stay a secret
    secret_name: str = Field(
            sa_column=Column(
                    EncryptedType(
                            sqlalchemy.Unicode,
                            os.getenv('ENCRYPTION_KEY'),
                            AesEngine,
                            'pkcs5'
                            )
                    )
            )
    age: Optional[int] = None


sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"

engine = create_engine(sqlite_url, echo=True)


def create_db_and_tables():
    SQLModel.metadata.create_all(engine)


def create_heroes():
    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")  #
    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")  #
    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)  #

    print("Before interacting with the database")  #
    print("Hero 1:", hero_1)  #
    print("Hero 2:", hero_2)  #
    print("Hero 3:", hero_3)  #

    with Session(engine) as session:  #
        session.add(hero_1)  #
        session.add(hero_2)  #
        session.add(hero_3)  #

        print("After adding to the session")  #
        print("Hero 1:", hero_1)  #
        print("Hero 2:", hero_2)  #
        print("Hero 3:", hero_3)  #

        session.commit()  #

        print("After committing the session")  #
        print("Hero 1:", hero_1)  #
        print("Hero 2:", hero_2)  #
        print("Hero 3:", hero_3)  #

        print("After committing the session, show IDs")  #
        print("Hero 1 ID:", hero_1.id)  #
        print("Hero 2 ID:", hero_2.id)  #
        print("Hero 3 ID:", hero_3.id)  #

        print("After committing the session, show names")  #
        print("Hero 1 name:", hero_1.name)  #
        print("Hero 2 name:", hero_2.name)  #
        print("Hero 3 name:", hero_3.name)  #

        session.refresh(hero_1)  #
        session.refresh(hero_2)  #
        session.refresh(hero_3)  #

        print("After refreshing the heroes")  #
        print("Hero 1:", hero_1)  #
        print("Hero 2:", hero_2)  #
        print("Hero 3:", hero_3)  #
    #

    print("After the session closes")  #
    print("Hero 1:", hero_1)  #
    print("Hero 2:", hero_2)  #
    print("Hero 3:", hero_3)  #


def main():
    create_db_and_tables()
    create_heroes()


if __name__ == "__main__":
    main()

Description

This code is already working as is!

I did not find a tutorial for SLQModel on how to encrypt / decrypt data. I also thought of opening a PR to add this to the docu but as this approach uses a separate package (sqlalchemy_utils) for the column type EncryptedType I wanted to ask beforehand if that is wanted.

Operating System

Linux

Operating System Details

No response

SQLModel Version

0.0.8

Python Version

3.10.4

Additional Context

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
investigate question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants