Deep Dive Into the Repository Design Pattern in Python

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
it's been a while since I did a video covering a software design pattern I'm running out of patterns but then I remembered one pattern I haven't talked about is the rep poost story design pattern it's actually a nice pattern that helps you separate how you store data from the operations you perform on the data now if you want to know more about decisions I make when designing software from scratch check out my free software design guide where I go over seven steps I take when I design a new application you can find it at ion. COD D design guide or by clicking the link in the description below now let's dive into the repository pattern I want to start with an example of how you could interact with a database using classes functions methods in Python so here what I'm doing is that I'm using sqlite of course you can also connect with database in the cloud if you want to but this is just so that it works locally and I can show it to you quickly so there's a couple of things here so first we have a connection function so this connects with a sqlite database and returns a cursor and then we can use the cursor to interact with the database also what I've done here is I've created a post data class that represents a post in the database and I've added a couple of class methods to it to have basic interaction with the database and from SQL queries so a post has three Fields a title content and an ID so this could be a blog post for example and then we have a couple of methods so there's a class method create table that gets path to dat datase if you were connecting over the cloud this would be a database connection stream we connect to the database that gives us a cursor so that's where we using this connect method and then we create a post table if that doesn't exist that has an ID a title and content and then we have a couple of other class methods to help us interact with the database more easily so I have a get post method that gets a post ID and the path to the database so we connect to the database and then we find the post using a SQL query and then we return a post object containing the title content and the ID that we extract from the post that we got from the SQL query and then we have a couple of other methods as well to kind of fill out the crop operation so we have get all post that gets a list of all the posts from the database we have ADD post update post and delete post and each of these very basic we simply translate them into SQ queries to perform the specific task that we need to do then in the main function we initialize the database so we provide it with a SQL light database file name if that doesn't exist it creates it and then we add a couple of posts and every time we pass the reference to the database one way to improve this would be to move this to a Conant so we don't have to repeat it everywhere another thing that we could do is to actually store this reference internally in the post object so that we can then refer to it whenever we add or remove or update posts with it so we create a few posts and then we get all the posts and then we print them so when we run this code then this is what we get pretty basic right now the issue in setting up your code in this way is that the representation of the object the post is very tightly coupled with the way that you interact with the database and that can lead to complications because if you have many different types of objects in the database maybe not only posts but also authors and other types of content or if your tables have many many different columns then creating all these SQL queries becomes kind of commers on them and you have to repeat that all over the place and of course all these objects are going to look pretty similar for post for authors you're going to have to do kind of the same sort of kind of thing so that's complicated also if you ever decide to switch to I don't know no SQL database for example or maybe you just want to store it in a text file then you need to change a lot of things in your code now one way to solve that would be to use an omm like SQL Alchemy but then you're still tied to SQL databases because SQL Alchemy doesn't support storage options that are not SQL based and finally by doing it this way it also makes it hard to write test for this because everything is so tightly cobbled so in short with this setup if we want to change how we store the data we also need to change how we access the data because it's also tightly coupled and this is where the repository pattern can be of help and this is a design pattern that separates how we store data from how we access the data by separating these concerns of on the one hand storing data and on the other hand accessing data we make our code easier to maintain and easier to extend so like I mentioned the repository pattern is not just for databases so it's it's actually broader than an or in that sense which is often for a specific type of database you can do this for many different types of storage you can also use the repos story pattern for an object store for example or a key value store or any other type of storage that you might be using here's a slightly different way of setting this up using the repost story pattern so what I'm doing here is I still have my post class but it's now simply a data class containing an ID title and content so there are no implementation details here about how this is stored whether that's in a database or in a text file or anywhere else also what I've done here is I've created a repository class that's an abstract Base Class that has a couple of abstract methods that are not implemented here so the Aras a not implemented error but they correspond to the standard types of storage and retrieval operations that you would like to do getting an item getting all of the items adding something updating something and deleting something as you can see there's nothing here about how these things are stored it just tells the repository to get the thing or to delete the thing or to update the thing how that's implemented we don't really care about that and on top of that what I've done is that I'm using the python 3.12 generics mechanism here so this is a repository of types T So a get operation returns something of type t get all returns list of T and this means that we can now use this repost or structure for any type T including for post so what I've done now is create an implementation here for posts that are stored in a database so the post repository then has the initializer that gets a path to the database it creates the tables by calling this particular method here it has the connection logic because that's all part of the database integration right and then here we have all the different repository methods that we need to implement so get get all add and um update and delete Etc but as you can see the post type is in principle independent from this repository it's merely used as a container for the data in the Python program so now the repost story contains all of the SQL statements to modify the database and you can imagine that now you could actually build this out this repository pattern and turn it into an orm like thing where we we would not have a post report story but we would have a SQL database report story where we could make the statements generic and simply replace the names of the tables and the columns that we need with settings from schema so in essence that means that if you look at tools like SQL Alchemy there are actually sort of implementations of the repository pattern except that they're focused on SQL databases so you could take it to the next level and create a very generic I don't know Alchemy library that has report story implementations for a 100 different things including SQL databases but also no SQL object stores files anything that you like as long as the interface the schema the structure of the data is separated from how you store it and here I have a main function where I create theost story then I add a couple of posts I print them I update them delete them and if you run this then this is what the program outputs question have you explicitly used the repost story pattern before or maybe you didn't even realize that you were using it that happens to me all the time let me know in the comments so one thing that's nice about the reposter pattern is that it allows you to do testing much more easily so in this case what I've done is I've created a new class called mock post repost story that's basically a fake repost story and what I did here is that you can basically Supply it with a dictionary of post and now the implementation of all these crud methods simply gets them from the dictionary so this is a really easy way of writing test because now the way that we store the data is separate from the representation of the data so we have a mock post reposter and then with that mock repository you can write your tests so for example here I create a mock post repository I add a new post and then I check that the first one is indeed a post with a given ID and the correct data now obviously this will not allow you to test the inner workings of a database oriented repost story you're going to need to write separate unit test for that yourself so now we can simply write our tests that rely on the mock post repository and if we ever Define a function for example that needs to work with posts and needs to perform some sort of operation then in the production version of the code it would get a real report story that would connect with the database and in the test we can then provide it with a mock repost story and then test that it actually performed the operations correctly now again if you use an omm like SQL Alchemy this is actually going to be sort of built into the omm right because they will have a mechanism for you to test that properly so you won't have to develop that yourself but in principle that's how the repository pattern works so the question is would you actually use this and in what cases would you use now typically this is not something that you're going to build yourself very often many cases an omm is actually precisely what you need and then you simply use the omm but that does assume that you don't plan to switch from a let's say SQL database to a nosql solution now if you know in the future that that might happen or or you might want to have different options of accessing the data you want to make your application really generic then implementing a repost story pattern as an interface between your application and how you store the data might be a good option for you so that's something that you're going to have to think of yourself whether you are willing to add that extra boilerplate code that the repository pattern introduces in order to benefit from that also if you add extra classes and things like that it might result in some performance overhead because well you need to create all of those objects in memory Etc an issue though with the repository pattern is that you are limited to the methods that you implement in the repository interface so in this case we've built simple crop operations right at getting updating and deleting but what if you want to do more than that of course the SQL language is built to do more with data it's built to do things like querying data and filtering and doing lots of complicated queries on data so it's also a Pity to throw that capability out of the window so you could then Implement all of those things basically building a complete orm but then it means if you want to swap out your SQL database with a nosql solution you're going to have to rebuild all of those features as a layer on top of your nosql solution so that's also not ideal either and then there are other types of varieties that you can think about such as a SQL query builder for example so in short using the repository pattern does make your code more modular but that's extra boiler plate code and if you need let's say detailed interactions with your data then it can quickly become a lot of work so you have to be mindful of that now specifically in the case of SQL database there are other things that you need to think about whether you should just use raw SQL statements use an omm use a SQL query Builder and did a full video about that you can watch that right here thanks so much for watching and see you next time
Info
Channel: ArjanCodes
Views: 63,189
Rating: undefined out of 5
Keywords: design pattern python, design patterns in python, design patterns python, repository design pattern python, python design patterns, programming design patterns, repository design pattern, design patterns explained, design pattern programming, design pattern tutorial, python pattern, repository python pattern, arjancodes, arjancodes python, arjancodes design patterns, arjancodes tutorial, programming python, programming patterns, python programming, python programming tutorial
Id: 9ymRLDfnDKg
Channel Id: undefined
Length: 11min 55sec (715 seconds)
Published: Fri Jan 26 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.