Why Dataclasses Disappear in Real Python Applications
Key Takeaways
The video discusses the use of Python dataclasses in real-world applications, comparing them to alternative tools like Pydantic, FastAPI, and SQLAlchemy, and provides examples of when to use dataclasses and when to use other tools.
Full Transcript
Let me show you something interesting. This is our main repo with a bunch of uh different automations. It's basically most of the Python code that we write at RN code is in this backend repo. This does a bunch of stuff. It integrates with APIs, databases. It's uh listens to events from payment providers, etc. Let me search for data classes. Now, as you can see, there is my examples repo as well that has uh what is it? Almost 800 uses of data classes, but my back end repo doesn't even show up here. It looks like I'm not using data classes at all in our back end. So, when I first noticed this, I was very surprised. Like, what? I'm promoting data classes all over the channel. Basically, really like the feature in Python, and when I look for it, we're not even using it. what's going on? But then I realized I am actually still using data classes, but probably not in the way that you think. But before I talk about that, let's do a quick recap of what data classes in Python actually do and how it differs from other third-party packages such as Pyantic. In short, I've already talked about this in lots of other videos. A data class is a simple way to create classes that store data, and it's part of the data classes module. And this is part of the Python standard library. So what you can do is you can specify a decorator and then you can create a class let's say a book. And that book has a title and it may have an author, it may have a year, it may have other things as well. And the nice thing about data classes is that you can specify the instance variables in this way. And then the data class decorator is going to automatically create an initializer for you. It's going to create a wrapper for this particular book class. It's going to do object comparison and a couple of other things as well. So because this is now data class, I can simply create a book and then I can print that book and when I run this then this is what we get. So it gives me a nice useful representation. Whereas if this is not a data class, so now there's all sorts of things that are not there. For example, the book initializer is basically empty because it's not being generated. So I need to do that manually. And also when I print it, it's not going to give me a lot of information because if I create a book like so and uh then I run this then it gives me an book object very low-level thing at some memory address right so data class solve that problem and make it easier to deal with classes and object that contain data. Now, there's lots of other cool features that they add such as a frozen option read only. You have control over what should be added as an argument to the initializer. Uh being able to use slots for better performance and a bunch of other things. Like I said, it's part of the standard library for quite a while since Python 3.7, so there's no external dependencies. It's tied to Python's own versioning, which can be helpful, and that means it's easy to maintain across different environments. That's actually a huge win. um especially compared to third party libraries that sometimes well let's say disagree with each other. In short, data classes sound like a great feature. So why am I not using it? Well, before I talk about that, let's first go over some of the alternatives. And the main one that I want to mention is Pyantic. Pyantic is a bit like data classes. It's not part of the standard library, but the main thing that Pyantic adds is validation plus a couple of other features as well. That's why it's used often by frameworks like fast API where you know validation is kind of useful if you have an API. Now in the past we had some compatibility issues because of that like fast API depended on paidantic v1 you had SQL alchemy for database access was also changing quite a bit and at the same time pantic v2 changed a lot of APIs and managing these versions wasn't always fun. If you were around in 2023, 2024, you probably remember like I mentioned, paid is deeply integrated into fast API in the request and response models. There's validation and parsing. Uh there's a type coercion. That's also feature of pideantics of converting a string one two three into an int one two three automatically. So that means it's really natural to use fast API and pideantic together. Here you see an example of that. So I have a fast API app. I have my book class for which I'm not using a data class because well it's easier with fast API to use pyantic because that's what it integrates with. We have a function to generate some ID. I just built something that looks a bit like a MongoDB object ID and then you have a bunch of endpoints right creating book getting a book listing books etc. Pretty basic. And then we can run this API. And this is pretty straightforward using UV. And what you can do now is send a request. So in this case, I'm sending a request to this API that receives books. And as you can see, of course, uh when you create this, there is simply an empty dictionary. There is no books whatsoever. There's nothing here. But then what I can do is post a request to create a book. And then later on when I retrieve the list of books then this is what I get. So very basic way of how an API works. Right now an issue here is that book right here is used for both representing a book and for representing what a request like creating a book expects right it's also being used here. And that's not great because you would expect a book in a database for example to have some sort of ID. And it also results in a weird design where if you look at create book, we have to return this dictionary containing an ID and the actual book. And same for get book. So it gets an ID and it gets a book from the dictionary. And that's kind of confusing. Ideally, you'd want to return purely a list of book objects, but that's not possible because a book here doesn't have an ID. I could add an ID, but then I'd need to supply it when creating a book. Okay, you can maybe make it optional, but the list of books that you store in your uh database or in your memory, well, books need an ID, so it's not optional. So, it's it's not really a Python problem actually or a fast API or a financing problem. This is actually a data modeling problem. So, you might wonder, well, is that maybe a place where you could use data classes? And the answer is yes, maybe. So here's another version of that API that now uses a data class book class to model the internal representation of a book right and as you can see it has an ID field now which uses generate ID as a default factory so when you create a book instance it's going to create an ID and then on top of that we have now new pantic models for creating a book which has a title author and pages and for a book response which is an ID, a title, author and pages. I have my fake database again and then I have my routes and now I can do uh this where I'm basically supplying a response model. So that gives my fast API app the information about what kind of thing this response and same thing for getting the books. The response model is a book response and for getting all the books we have a list of book response objects. So that's very neat. So you might say okay great. So that's what we can use data classes for. But of course in a real application this is probably not what you would do. In a real application you'd probably use a database and the package that you might commonly use for this is SQL alchemy. And this is the same example but this time around it works with a real database or at least it works with a SQLite database but you can change this URL so that it's a real database in a cloud. So very simply said, I have my database engine setup stuff here. And then I have my SQL alchemy OM model. So that's basically what we had as a data class before where I have an ID, I have a title, author, and pages. And then again, I have my pyantic models for creating a book and returning a book. And then finally, well, we have some uh boiler plate code for getting the ID, which we're going to inject in the endpoints. That's what's happening here. And then finally, we interact with this database to uh create books, retrieve books, uh and everything that we want to do with books. So, what happened here is that we got a bit closer to what a production application would look like. The data classes disappeared. Now, it's possible that you actually still like the data classes approach of having a data class decorator, right? instead of this uh inheritance relationship that we have here. Well, Pideantic does support two ways of defining the models. So, this is the classic way of doing it, but there's also a newer way of doing it, which is using paidic style data classes and that's what this looks like. So, it's very close to how the built-in data classes works as you can see right here. So, you can use either of these two. There are some differences between pideantic style data classes and the base model in a sense base model has more features because the pyantic data class follows the standard library data class very closely. Here have another example where I'm using both uh data class and the base model to define various types of models. So I have a book model for example using the podantic data class as type one pages and it has a validator to check that pages is positive. That's one of the things you can do with pyantic, right? And then I have an author class that is a base model. So that's the other way of defining the models in pyantic. It also has a valid data by h. Now there are some limitations to pyantic style data classes because it closely follows the standard library implementation of it. One of them is that it doesn't do type coercion. So if you create let's say a book uh with uh string pages that doesn't work. Whereas for an author uh you can actually do that. So for example, if I run this code where I try to create a bad book with a string as pages, then it's going to result in a validation error. As you can see, it wants input to be a valid integer. However, if I have the author here, which is a base model, bantic model, and I change age to be a string like so. So of course, I get a type issue here. However, if I run this, then I don't get any error at all. It simply just converts the type into an int. And there's more missing features from the paid style data classes. For example, you can't do model dump which creates a dictionarial JSON style version of the object because model dump is not implemented on that. It's only implemented on the base model. So even though pyantic data class may feel more Pythonic, they do lack a lots of important features. Finally, these pyantic style data classes don't work all that well with fast API. For example, if you try to change the response model to a pyantic data class, it doesn't work. By the way, if you want to learn how to design better software from scratch, check out my free design guide at code/design guide. This includes the seven steps that I use for building real project. Links in description. So even pyantic style data classes are actually too limited. So it looks like that whatever I do it I seem to end up with code that doesn't use data classes. What these examples show is that when you're looking at production code you're often dependent on data structures that are used by your favorite libraries. Fast API, SQL Alchemy, Pandas, etc. And typically just the standard library data classes don't have the required features that those libraries need. So they use something else. Fast API needs extensive validation. So it uses binance and not the built-in data classes. Pandas has its own data frame structure. It doesn't use a data class for each row in a data frame because that's not efficient enough and it's missing important features. And since we often rely on libraries like this to write our Python code, you're going to use those structures instead of data class from the standard library. So it seems like data classes are mostly useless then. But here's the interesting thing. I actually still use data classes. And how I like to use them is not for these types of scripts or automations. I actually use them a lot for prototyping. For example, if I'm trying to come up with a model for a certain domain and uh get an understanding of how everything works together, I could of course make a bunch of diagrams with mermaid, you know, write some stuff in markdown or whatever or I could uh get a paper and a pen or do it in KFA or whatever or use some of these online drawing tools. Now instead what I like to do is define a couple of data classes, one for each concept in the domain and then I use chat GPT a lot to then discuss the domain and iterate over that Python code. And for me that actually works really well because I find data classes is really easy to read. It's very quick to just write a data class, code up some relationships between classes, write some simple example code to figure out how it all fits together, etc. So to me data class are really useful for well let's just call it what it is vibe domain modeling and of course I use data class a lot in my examples because they allow me to give you a very simple representation of something without having to depend on a database or other things. But I'd like to hear from you. Do you use data classes in production code? What's your main use case for them? I'd love to hear your thoughts. Now, I've talked about pedantic and data classes before, and there's also at the package that data classes are based on. If you want to learn more about that and see a deeper comparison between the pros and cons of each, check out this video next. Thanks for watching and see you next
Original Description
💡 Learn how to design great software in 7 steps: https://arjan.codes/designguide.
In this video, I take a deep dive into Python dataclasses in 2025. Are they still useful now that we have Pydantic, FastAPI, SQLAlchemy, and other tools? I walk through real-world examples showing when you should use dataclasses, Pydantic models, and how to design your models cleanly. I’ll also build a small FastAPI app with SQLAlchemy and SQLite to demonstrate proper separation between domain models and API schemas.
🔥 GitHub Repository: https://git.arjan.codes/2025/dataclasses.
🎓 ArjanCodes Courses: https://www.arjancodes.com/courses.
💬 Join my Discord server: https://discord.arjan.codes.
⌨️ Keyboard I’m using: https://amzn.to/49YM97v.
🔖 Chapters:
0:00 Intro
1:11 Quick Refresher – What Are Dataclasses?
4:09 Dataclasses vs Pydantic – And a Real FastAPI Example
6:36 Separate Domain and API Models
8:51 Hybrid Approach in Pydantic
11:53 When Do I Use Dataclasses
14:03 Final Thoughts
#arjancodes #softwaredesign #python
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from ArjanCodes · ArjanCodes · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Full stack WEB DEVELOPMENT in 2021 - the ULTIMATE tech stack for FAST web app development
ArjanCodes
FROM PRODUCT IDEA TO SOFTWARE - turn your idea into reality in a few steps
ArjanCodes
Cohesion and Coupling: Write BETTER PYTHON CODE Part 1
ArjanCodes
Build a GLASSMORPHISM React Component - Typescript & Material-UI
ArjanCodes
Observer Pattern Tutorial: I NEVER Knew Events Were THIS Powerful 🚀
ArjanCodes
100% CODE COVERAGE - Think You're Done? Think AGAIN.☝
ArjanCodes
Two UNDERRATED Design Patterns 💡 Write BETTER PYTHON CODE Part 6
ArjanCodes
1000 Subscribers! 🚀 WHY I Started this Channel and WHAT'S NEXT
ArjanCodes
Channel Trailer ArjanCodes - March 2021
ArjanCodes
Exception Handling Tips in Python ⚠ Write Better Python Code Part 7
ArjanCodes
Monadic Error Handling in Python ⚠ Write Better Python Code Part 7B
ArjanCodes
GW BASIC Games I Wrote When I Was a Kid 🎮 Running 30 Year Old Code
ArjanCodes
Why You Should Think About SOFTWARE ARCHITECTURE in Python 💡
ArjanCodes
Uncle Bob’s SOLID Principles Made Easy 🍀 - In Python!
ArjanCodes
QUESTIONABLE Object Creation Patterns in Python 🤔
ArjanCodes
If You’re Not Using Python DATA CLASSES Yet, You Should 🚀
ArjanCodes
CODE ROAST: Yahtzee - New Python Code Refactoring Series!
ArjanCodes
7 UX Design Tips for Developers
ArjanCodes
Going All-in on Software Design in Python + an ANNOUNCEMENT 🎙
ArjanCodes
🎙 Interview with Sybren Stüvel, Developer @ Blender 3D
ArjanCodes
Do We Still Need Dataclasses? // PYDANTIC Tutorial
ArjanCodes
7 Python Mistakes That Instantly Expose Junior Developers
ArjanCodes
Answering Your Most Frequently Asked Python Questions // Q&A 07-2021
ArjanCodes
GitHub Copilot 🤖 The Future of Software Development?
ArjanCodes
More Python Code Smells: Avoid These 7 Smelly Snags
ArjanCodes
Test-Driven Development In Python // The Power of Red-Green-Refactor
ArjanCodes
5 Tips To Keep Technical Debt Under Control
ArjanCodes
Refactoring A Tower Defense Game In Python // CODE ROAST
ArjanCodes
The Factory Design Pattern is Obsolete in Python
ArjanCodes
Why the Plugin Architecture Gives You CRAZY Flexibility
ArjanCodes
Refactoring A Data Science Project Part 1 - Abstraction and Composition
ArjanCodes
Refactoring A Data Science Project Part 2 - The Information Expert
ArjanCodes
Refactoring A Data Science Project Part 3 - Configuration Cleanup
ArjanCodes
Purge These 7 Code Smells From Your Python Code
ArjanCodes
Running A Software Development YouTube Channel
ArjanCodes
Refactoring A PDF And Web Scraper Part 1 // CODE ROAST
ArjanCodes
Refactoring A PDF And Web Scraper Part 2 // CODE ROAST
ArjanCodes
How To Easily Do Asynchronous Programming With Asyncio In Python
ArjanCodes
The Software Designer Mindset
ArjanCodes
NEVER Worry About Data Science Projects Configs Again
ArjanCodes
Powerful VSCode Tips And Tricks For Python Development And Design
ArjanCodes
8 Python Coding Tips - From The Google Python Style Guide
ArjanCodes
What Is Encapsulation And Information Hiding?
ArjanCodes
8 Tips For Becoming A Senior Developer
ArjanCodes
Building A Custom Context Manager In Python: A Closer Look
ArjanCodes
GraphQL vs REST: What's The Difference And When To Use Which?
ArjanCodes
You Can Do Really Cool Things With Functions In Python
ArjanCodes
Announcing The Black VS Code Theme (Launching April 1st)
ArjanCodes
7 DevOps Best Practices For Launching A SaaS Platform
ArjanCodes
Refactoring a Rock Paper Scissors Lizard Spock Game // Code Roast Part 1
ArjanCodes
Refactoring a Rock Paper Scissors Lizard Spock Game // Part 2
ArjanCodes
Things Are Going To Change Around Here
ArjanCodes
Dependency Injection Explained In One Minute // Python Tips
ArjanCodes
How To Setup A MacBook Pro M1 For Software Development
ArjanCodes
A Simple & Effective Way To Improve Python Class Performance
ArjanCodes
How To Write Unit Tests For Existing Python Code // Part 1 of 2
ArjanCodes
How To Write Unit Tests For Existing Python Code // Part 2 of 2
ArjanCodes
Make Sure You Choose The Right Data Structure // Python Tips
ArjanCodes
5 Tips For Object-Oriented Programming Done Well - In Python
ArjanCodes
Next-Level Concurrent Programming In Python With Asyncio
ArjanCodes
More on: Data Literacy
View skill →Related Reads
📰
📰
📰
📰
Beyond console.log: Advanced Debugging Workflows That Will Save You Hours
Medium · JavaScript
cgo Overhead Dropped 30%. When Should You Actually Care?
Medium · Programming
Why Everyone is Wrong About Website Development?
Medium · Programming
The Silent Killer in Your Node.js APIs: Mass Assignment & How to Catch It Before Production
Medium · Programming
Chapters (7)
Intro
1:11
Quick Refresher – What Are Dataclasses?
4:09
Dataclasses vs Pydantic – And a Real FastAPI Example
6:36
Separate Domain and API Models
8:51
Hybrid Approach in Pydantic
11:53
When Do I Use Dataclasses
14:03
Final Thoughts
🎓
Tutor Explanation
DeepCamp AI