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
Organize seu linux - organize your linux

OrganizeLinux Organize seu linux - organize your linux Organize seu linux Uma forma rápida de separar arquivos dispersos em pastas. formatos a serem c

Marcus Vinícius Ribeiro Andrade 1 Nov 30, 2021
Movie recommend community

README 0. 초록 1) 목적 사용자의 Needs를 기반으로 영화를 추천해주는 커뮤니티 서비스 구현 2) p!ck 서비스란? "pick your taste!" 취향대로 영화 플레이리스트(이하 서비스 내에서의 명칭인 '바스켓'이라 함)를 만들고, 비슷한 취향을 가진

2 Dec 08, 2021
An unofficial python API for trading on the DeGiro platform, with the ability to get real time data and historical data.

DegiroAPI An unofficial API for the trading platform Degiro written in Python with the ability to get real time data and historical data for products.

Jorrick Sleijster 5 Dec 16, 2022
uMap lets you create maps with OpenStreetMap layers in a minute and embed them in your site.

uMap project About uMap lets you create maps with OpenStreetMap layers in a minute and embed them in your site. Because we think that the more OSM wil

771 Dec 29, 2022
An a simple sistem code in python

AMS OS An a simple code in python ⁕¿What is AMS OS? AMS OS is an a simple sistem code writed in python. This code helps you with the cotidian task, yo

1 Nov 10, 2021
Using graph_nets for pion classification and energy regression. Contributions from LLNL and LBNL

nbdev template Use this template to more easily create your nbdev project. If you are using an older version of this template, and want to upgrade to

3 Nov 23, 2022
Moleey Panel with python 3

Painel-Moleey pkg upgrade && pkg update pkg install python3 pip install pyfiglet pip install colored pip install requests pip install phonenumbers pkg

Moleey. 1 Oct 17, 2021
Improving the Transferability of Adversarial Examples with Resized-Diverse-Inputs, Diversity-Ensemble and Region Fitting

Improving the Transferability of Adversarial Examples with Resized-Diverse-Inputs, Diversity-Ensemble and Region Fitting

Junhua Zou 7 Oct 20, 2022
A python script to run any executable and pass test cases to it's stdin and compare stdout with correct output.

quera_testcase_checker A python script to run any executable and pass test cases to it's stdin and compare stdout with correct output. proper way to u

k3y1 1 Nov 15, 2021
A Brainfuck interpreter written in Python.

A Brainfuck interpreter written in Python.

Ethan Evans 1 Dec 05, 2021
MinimalGearDisplay, Assetto Corsa app

MinimalGearDisplay MinimalGearDisplay, Assetto Corsa app. Just displays the current gear you are on. Download and Install To use this app, clone or do

1 Jan 10, 2022
propuestas electorales de los candidatos a constituyentes, Chile 2021

textos-constituyentes propuestas electorales de los candidatos a constituyentes, Chile 2021 Programas descargados desde https://elecciones2021.servel.

Sergio Lucero 6 Nov 19, 2021
Purge your likes and wall comments from VKontakte. Set yourself free from your digital footprint.

vk_liberator Regain liberty in the cruel social media world. This program assists you with purging your metadata from Russian social network VKontakte

20 Jun 11, 2021
Modify the value and status of the records KoboToolbox

Modify the value and status of the records KoboToolbox (Modica el valor y status de los registros de KoboToolbox)

1 Oct 30, 2021
Simple project to assist in tracking/logging my working hours

Fill working hours Basic script to assist in the logging/tracking of my working hours How it works Create a file called projects.json in this director

Robin Kennedy-Reid 2 Oct 31, 2022
A python program with an Objective-C GUI for building and booting OpenCore on both legacy and modern Macs

A python program with an Objective-C GUI for building and booting OpenCore on both legacy and modern Macs, see our in-depth Guide for more information.

dortania 4.7k Jan 02, 2023
Adversarial Robustness with Non-uniform Perturbations

Adversarial Robustness with Non-uniform Perturbations This repository hosts the code to replicate experiments of the paper Adversarial Robustness with

5 May 20, 2022
This repository collects nice scripts ("plugins") for the SimpleBot bot for DeltaChat.

Having fun with DeltaChat This repository collects nice scripts ("plugins") for the SimpleBot bot for DeltaChat. DeltaChat is a nice e-mail based mess

Valentin Brandner 3 Dec 25, 2021
Let's pretend you want to create a AWS Lambda project called "sns-processor".

Usage Let's pretend you want to create a AWS Lambda project called "sns-processor". Rather than using lambda and then editing the results to include y

1 Dec 31, 2021
适用于HoshinoBot下的雀魂插件。可进行近期对局查询、查询个人数据等功能,更多功能正在扩展

Majsoul_bot This is a Majsoul plugin for HoshinoBot 这是一个HoshinoBot的雀魂相关插件 本项目目前正在扩展,后续会扩展更多功能,敬请期待 前言 项目地址:https://github.com/DaiShengSheng/Majsoul_bo

黛笙笙 33 Dec 14, 2022