Tools to convert SQLAlchemy models to Pydantic models

Overview

Pydantic-SQLAlchemy

Test Publish Coverage Package version

Tools to generate Pydantic models from SQLAlchemy models.

Still experimental.

How to use

Quick example:

from typing import List

from pydantic_sqlalchemy import sqlalchemy_to_pydantic
from sqlalchemy import Column, ForeignKey, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session, relationship, sessionmaker

Base = declarative_base()

engine = create_engine("sqlite://", echo=True)


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    nickname = Column(String)

    addresses = relationship(
        "Address", back_populates="user", cascade="all, delete, delete-orphan"
    )


class Address(Base):
    __tablename__ = "addresses"
    id = Column(Integer, primary_key=True)
    email_address = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey("users.id"))

    user = relationship("User", back_populates="addresses")


PydanticUser = sqlalchemy_to_pydantic(User)
PydanticAddress = sqlalchemy_to_pydantic(Address)


class PydanticUserWithAddresses(PydanticUser):
    addresses: List[PydanticAddress] = []


Base.metadata.create_all(engine)


LocalSession = sessionmaker(bind=engine)

db: Session = LocalSession()

ed_user = User(name="ed", fullname="Ed Jones", nickname="edsnickname")

address = Address(email_address="[email protected]")
address2 = Address(email_address="[email protected]")
ed_user.addresses = [address, address2]
db.add(ed_user)
db.commit()


def test_pydantic_sqlalchemy():
    user = db.query(User).first()
    pydantic_user = PydanticUser.from_orm(user)
    data = pydantic_user.dict()
    assert data == {
        "fullname": "Ed Jones",
        "id": 1,
        "name": "ed",
        "nickname": "edsnickname",
    }
    pydantic_user_with_addresses = PydanticUserWithAddresses.from_orm(user)
    data = pydantic_user_with_addresses.dict()
    assert data == {
        "fullname": "Ed Jones",
        "id": 1,
        "name": "ed",
        "nickname": "edsnickname",
        "addresses": [
            {"email_address": "[email protected]", "id": 1, "user_id": 1},
            {"email_address": "[email protected]", "id": 2, "user_id": 1},
        ],
    }

Release Notes

Latest Changes

0.0.9

  • Add poetry-version-plugin, remove importlib-metadata dependency. PR #32 by @tiangolo.

0.0.8.post1

  • 💚 Fix setting up Poetry for GitHub Action Publish. PR #23 by @tiangolo.

0.0.8

  • ⬆️ Upgrade importlib-metadata to 3.0.0. PR #22 by @tiangolo.
  • 👷 Add GitHub Action latest-changes. PR #20 by @tiangolo.
  • 💚 Fix GitHub Actions Poetry setup. PR #21 by @tiangolo.

0.0.7

  • Update requirements of importlib-metadata to support the latest version 2.0.0. PR #11.

0.0.6

0.0.5

  • Exclude columns before checking their Python types. PR #5 by @ZachMyers3.

0.0.4

  • Do not include SQLAlchemy defaults in Pydantic models. PR #4.

0.0.3

  • Add support for exclude to exclude columns from Pydantic model. PR #3.
  • Add support for overriding the Pydantic config. PR #1 by @pyropy.
  • Add CI with GitHub Actions. PR #2.

License

This project is licensed under the terms of the MIT license.

Comments
  • custom orm instead of model translation?

    custom orm instead of model translation?

    Hi, I had the same problem with maintaining two sets of models and took inspiration from encode/orm (not finished) and ormantic (not maintained) and started ormar that uses encode/databases and sqlalchemy core under the hood, and can be used in async mode. @tiangolo feel free to check it out and let me know if you find it useful!

    answered 
    opened by collerek 4
  • Attempt to exclude columns before determining type

    Attempt to exclude columns before determining type

    I have some tables that I'd like to exclude some fields that don't have a python type in sqlalchemy. I'd like to keep them in my model and process them into pydantic manually after the other fields get processed with this utility, but the exclude logic runs after the determination of the type, so I get a NotImplementedError() regardless of exclusion in this case.

    I'd like to just move the exclusion logic above the type determination, so that this wouldn't occur in my use-case.

    opened by ZachMyers3 4
  • which framework to use for model translation

    which framework to use for model translation

    Hi there,

    thanks for all your efforts in getting this model translation to work! Really appreciated. Upon a quick search (there really seems to be an entire zoo of possible orm's + pydantic + graphene models etc. etc.) I came upon this: https://github.com/kolypto/py-sa2schema From the descriptions and listed examples it seems they are trying to achieve the same thing.

    Now the hard question: which one should I use? Any opinions on pro- & cons?

    Thanks, Carsten

    answered 
    opened by camold 3
  • Do not include defaults in models

    Do not include defaults in models

    :bug: Do not include defaults from SQLAlchemy models in Pydantic models.

    SQLAlchemy defaults are supposed to be generated at insertion/update time, not generated by the Pydantic model before creating a new object/record.

    It's also currently broken, as the default included is a SQLAlchemy object, not an actual default.

    opened by tiangolo 3
  • Can you add `depth` feature?

    Can you add `depth` feature?

    I think that the depth is a useful feature when serializing the model has many relationships like the DRF serializer's depth option

    Other libraries that it has depended on Pydantic

    • https://github.com/vitalik/django-ninja/blob/master/ninja/orm/factory.py#L29
    opened by ehdgua01 1
  • WIP: Add optional model name and only parameter to sqlalchemy_to_pydantic

    WIP: Add optional model name and only parameter to sqlalchemy_to_pydantic

    I went ahead and added the new_model_name parameter to close #51 . Will add tests as well.

    I also added an only field, that allows the reverse from exclude: only the mentioned fields will be included.

    I am also thinking to add a class that does something similar. Basically, you would inherit from it set what model you want to use (similar to Django's Meta class for e.g. views) and which fields and in the constructor it calls the sqlalchemy_to_pydantic function (using the new class name as model name) and creates the schema.

    investigate 
    opened by saschahofmann 3
  • Cannot generate two pydantic models from the same SQLAlchemy model

    Cannot generate two pydantic models from the same SQLAlchemy model

    For the create method of SQL model I need to exclude the id of a model, I'd like to call the sqlalchemy_to_pydantic function twice on the same model for example like this:

    PyUser = sqlalchemy_to_pydantic(User)
    PyUserCreate = sqlalchemy_to_pydantic(User, exclude=['id'])
    

    Now the server and every thing starts just fine but when I try to fetch the openapi.json, I get a keyerror because the first model is not in the model map.

    I think line 36 in main.py is at fault

    pydantic_model = create_model(
            db_model.__name__, __config__=config, **fields  # type: ignore
        )
    

    The db_model.__name__ is the same two times so it must be overwriting some key (Disclaimer: I have no idea about the inner workings of pydantic but it seems to be creating some kind of global map of all models?)

    I suggest to add an optional parameter name to the function and replace that line.

    opened by saschahofmann 0
  • Is this project still maintained?

    Is this project still maintained?

    Hi, I like this package, and personally, I used it twice in my little projects. There are some pull requests (including mine) that are not replied to. Is this project no longer maintained? Thanks.

    opened by bichanna 2
  • What about pydantic_to_sqlalchemy?

    What about pydantic_to_sqlalchemy?

    Using sqlalchemy_to_pydantic helped me a lot, but now I need the other way around. Is it supposed to be part of this library?

    Using SQLModel is no proper alternative to me, because it makes things harder, not easier right now.

    investigate 
    opened by mreiche 2
Releases(0.0.9)
Owner
Sebastián Ramírez
Creator of FastAPI, Typer, SQLModel. 🚀 SSE Forethought ➕ consulting. From 🇨🇴 in 🇩🇪. APIs & tools for data/ML. 🤖 Python, TypeScript, Docker, etc. ✨
Sebastián Ramírez
Python library to decode the EU Covid-19 vaccine certificate

DCC Utils Python library to decode the EU Covid-19 vaccine certificate, as specified by the EU. Setup pip install dcc-utils Make sure zbar is installe

Developers Italia 13 Mar 11, 2022
Python for Microscopists and other image processing enthusiasts

The YouTube channel associated with this code walks you through the entire process of learning to code in Python; all the way from basics to advanced machine learning and deep learning.

Dr. Sreenivas Bhattiprolu 2.3k Jan 01, 2023
How to access and display MyEnergi data

MyEnergi-Python-Example How to access and display MyEnergi data Windows PC Install a version of Python typically 3.10 The Python code here needs addit

G6EJD 8 Nov 28, 2022
AndroidEnv is a Python library that exposes an Android device as a Reinforcement Learning (RL) environment.

AndroidEnv is a Python library that exposes an Android device as a Reinforcement Learning (RL) environment.

DeepMind 814 Dec 26, 2022
Automated GitHub profile content using the USGS API, Plotly and GitHub Actions.

Top 20 Largest Earthquakes in the Past 24 Hours Location Mag Date and Time (UTC) 92 km SW of Sechura, Peru 5.2 11-05-2021 23:19:50 113 km NNE of Lobuj

Mr. Phantom 28 Oct 31, 2022
An OpenSource crowd-sourced cooking recipes website

An OpenSource crowd-sourced cooking recipes website

21 Jul 31, 2022
Displays Christmas-themed ASCII art

Christmas Color Scripts Displays Christmas-themed ASCII art. This was mainly inspired by DistroTube's Shell Color Scripts Screenshots ASCII Shadow Tex

1 Aug 09, 2022
WGGCommute - Adding Commute Times to WG-Gesucht Listings

WGGCommute - Adding Commute Times to WG-Gesucht Listings This is a barebones implementation of a chrome extension that can be used to add commute time

Jannis 2 Jul 20, 2022
GMHI: Gut Microbiome Health Index

GMHI: Gut Microbiome Health Index Description Gut Microbiome Health Index (GMHI)

Daniel Chang 2 Jun 30, 2022
Utility/Raiding selfbot made by Shell and Roover.

Utility/Raiding selfbot made by Shell and Roover. We are open to suggestions and ideas.

Shell 2 Dec 08, 2021
A custom advent of code I am completing

advent-of-code-custom A custom advent of code I am doing in python. The link to the problems I am solving is here: https://github.com/seldoncode/Adven

Rocio PV 2 Dec 11, 2021
Combines power of torch, numerical methods to conquer and solve ALL {O,P}DEs

torch_DE_solver Combines power of torch, numerical methods and math overall to conquer and solve ALL {O,P}DEs There are three examples to provide a li

Natural Systems Simulation Lab 28 Dec 12, 2022
Uproot - A script to bring deeply nested files or directories to the surface

UPROOT Bring deeply nested files or folders to the surface Uproot helps convert

Ted 2 Jan 15, 2022
easy_sbatch - Batch submitting Slurm jobs with script templates

easy_sbatch - Batch submitting Slurm jobs with script templates

Wei Shen 13 Oct 11, 2022
A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python

A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python

Windel Bouwman 277 Dec 26, 2022
Telegram bot for Urban Dictionary.

Urban Dictionary Bot @TheUrbanDictBot A star ⭐ from you means a lot to us! Telegram bot for Urban Dictionary. Usage Deploy to Heroku Tap on above butt

Stark Bots 17 Nov 24, 2022
Buffer overflow example for python

Buffer overflow example for python

Mehmet 1 Jan 04, 2022
This python module allows to extract data from the RAW-file-format produces by devices from Thermo Fisher Scientific.

fisher_py This Python module allows access to Thermo Orbitrap raw mass spectrometer files. Using this library makes it possible to automate the analys

8 Oct 14, 2022
Emulate and Dissect MSF and *other* attacks

Need help in analyzing Windows shellcode or attack coming from Metasploit Framework or Cobalt Strike (or may be also other malicious or obfuscated code)? Do you need to automate tasks with simple scr

123 Dec 16, 2022
Fully coded Apps by Codex.

OpenAI-Codex-Code-Generation Fully coded Apps by Codex. How I use Codex in VSCode to generate multiple completions with autosorting by highest "mean p

nanowell 47 Jan 01, 2023