Prisma ORM Tutorial for Beginners | CRUD, CreateMany, Associations...

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hey guys how's it going i'm back here with another video and today i decided to bring this video where i go over the prisma um arm library um and i just go over all the basics and also talk about some more advanced stuff we're gonna be building a very simple crud and node.js and um we're gonna be using mysql but you can use any database you want uh and i'll also show you guys some more advanced stuff like how to do associations or maybe how to insert uh many different um containers of data into a single table at the same time and before we actually get into the video if you guys could leave a like and subscribe if you're not subscribed i would massively appreciate it um we're growing at a very very rapid rate and i i couldn't be more thankful for that but if you guys leave a like it will push my videos to more people and youtube will know that um you guys are liking my videos so i'll my channel will go faster and i would really appreciate if guys could help me out with that so now that we got that out of the way let's start with the tutorial okay so prisma is um as you can see it's a next generation node.js and typescript orm and if you don't know what an arm is an arm is just a some sort of library that allows you to make database queries um sql queries um or it doesn't need to be sql but in this case we're going to be using an sql arm which allows you to make them without actually writing sql you just use simple javascript and the library itself to make those queries are to to basically manipulate your database and it makes it a lot easier it is very powerful and it is recommended for larger projects in my opinion i always use an arm it doesn't necessarily need to be prisma i have videos on sqlize and typeform which are other forms but prisma it is new it is growing at a very fast rate a lot of people are adapting to prisma and for that reason i decided to make this video so you can see that over here we have the the main website but i actually created um an application over here very simple um it only has a package.json as you can see and it has an index.ts which will be the the file where we start our application so prism is mainly used for typescript i'm not sure if you can use it for javascript but um it is probably one of the most famous typescript arms out there so the first thing we have to do if we want to start using prisma is we need to install the necessary packages right so i'm using yarn over here in this application but if you're using npm just convert the yarn logic to the npm logic and the first thing we want to do is we want to say yarn add or npm install if you're using npm then we want to say prisma because we want to install the prisma library then in this case we want to install typescript so we're going to say typescript then obviously to configure typescript we have to install ts node and also some typescript types on node so i'm going to say add types slash node and i'm going to say save dev at the end when we press enter it should be installing all the necessary packages but there are some more still some some configurations that we need to to make right um so the idea is we also want to in this case install express because express will be the the library that we're going to be using to create our rest api so we can say uh yarn add express and i also want to add the types the typescript types for express so i'm going to say add types slash express like this and we're gonna install this um very nice now we have express and um prisma in in our application i'm also gonna install node one uh just so that we can run our application and we don't need to keep saving our project every time we make any changes so i'll just install here nodemon into our app so now that we have that done let's start writing all the configurations for prisma so right over here we can just say um something really quick you can just come over here and say um npx prisma and it will initialize the prisma cli and then we just have to say npx prisma init and this will generate i believe a folder in our application called prisma which has a prisma a schema.prisma file which is it's going to be essential for us especially in the beginning to configure and connect to our database so in this prisma schema.prisma file you can see that there are two main components to it um the first one is the data source db over here and this is basically where you write a configuration information for your database so we're gonna be using mysql not postgres but if you're using postgresql just put it over here and then you can clearly see that it asks for a database url and it's using env for this so it's using env variables environment variables and when you run uh the c the prismacli as we just did it creates this dot env file where you can use and create um env variables and i'm just going to open this up so you guys can see everything a lot better but the thing is you can see that right now it gives us an example database url which we need to change to make it so that it will connect to our own database running in our local computer i actually already created my database i'm using mysql as i mentioned and i am using mysql workbench to make this work and i created this database called prismadb it has zero tables inside of it and if you're using postgres if you're using any like sql lite and any other type of database um then don't worry because the code will be exactly the same but the configuration will be a little bit different because you need to create your database before this so that you can connect it right um i'm doing everything in our root um in the the root server so basically um i'm gonna put the connection information based on that let's analyze this um what is this database url and how can we write our connection information over here so that it will work with our own database well the first thing you can see is that you need to write the the provider or which kind of rdbms you're using over here so in this case we're using mysql instead of postgres i'll put mysql over here um then we have here john doe and random password on this over here you need to put your user name um so the user for your database connection and here you need to put the password so if i go over here and i go to administration um in my mysql workbench you don't need to do this if you don't use it um i'm using actually a connection which is the the root one so actually i'll close this and you guys will see um this is the connection that i'm using um it's the local host connection so the name is localhost the port is 3033 or 3306. um and the username is root the password i know the password it's actually password that's the password that i gave but your password is probably different just put this sort of information directly into the url so the username is root i'm going to put this right over here instead of john doe the password in my case is password so i'm just going to put password in many cases the password might be root might be just an empty string it depends on your own system and then this should be localhost because in my case i'm running it on the localhost and the port as i showed you guys it is 3000 or 30 or three thousand three hundred and six so i'm gonna say 2306 like this and um finally over here we can leave this over here done um it should be public as well but this over here should be the actual database that you created so in our case i'm going to close this over here and enter this again and i need to put my password um i actually created this database in our app and our schemas over here you can see i called it prismadb it doesn't have any tables yet but this is what i called it so i need to put prisma db as the my as the the database name in our project so put prisma db like this and when i save this this will automatically come and and serve as the url for our database and the connection should be secured if there's any issues with this just leave a comment down below and maybe i'll help i can help you um i'm not that experienced with postgres and sqlite or other types of sql databases as i am with mysql so if it's an issue with that then maybe i can't help but if it's an issue with mysql i can definitely help you guys out in the comments down below so now what we have to do is we need to start building our schema so in prisma um you need to build your you need to build your tables and also in many other arms you need to build your tables or your models um in code without actually writing any sql so to actually build um your models or your tables you just come over here and you just write model and then the name of the table that you want to build so in this example project let's just create a users table so i'll say user and give it this name then um oh by the way one thing that i forgot to say is the reason why i have syntax highlighting for this prisma file is because i installed an extension called prisma i believe let me just come over here yeah install this one i recommend it it will give you syntax highlighting so it looks a lot better so we just created this model called user and we need to add its fields right so it's actual columns um what we want in the table so the first one needs to be id because that's a standard it will have an id as one of the columns i'm going to give it i'm going to say that it is an int which is an integer and we also can give it some other properties for example for an id on a table you usually want it to be out of incrementing right so to do that we'll just come over here and give it a default value and then give it pass it a function called auto increment and all of this like simple syntax all of this different properties that you can pass are very easily and well described in the um prisma documentation which i'm going to leave the link down below if you want to check it out but there's many different properties you can give to each attribute that you create in your model and then at the end we're going to say that we want to pass and make this an id so right below this we're going to pass differ a different field um let's say that our table takes in a username which is a string and probably our username wants it to we want it to be unique right we don't want two users to um have the same username so to make uh a field unique you literally just pass the unique property like this and then finally we're gonna pass the password over here and we're gonna say that it is a string it doesn't have to be unique uh people can have the same password so let's just leave it like this and i don't wanna over complicate this model but for now let's just keep it like this very simple and you might be thinking okay but how do i translate this into an actual table you can see that in our thing over here it doesn't have any tables um it's empty so to actually make it so that this will turn itself into a table in our database and actually this will also test our connection to see if we connect it successfully we can run a command in our command line which is going to migrate all the data that we have inside of this schema.prisma file into our actual database so to do that we'll just come over here and we're going to run npx prisma migrate and then we're gonna say dev for development and then we're gonna run two dashes name and then init and when we run this it's going to start running everything that is necessary for our migration to be done and really quickly you'll see that this will actually prob probably i hope um generate uh all the necessary files and also it will create our table so let's see if it works i'm going to refresh this this database and you can see that now we have um two new tables in our database one of them is called user and one is called prisma migrations i would ignore the prisma migrations one it basically just holds information about all the different migrations that you made throughout your your the time that you have this database but the important one is this one over here which is the users table it has all the fields that we um defined it to have so that's amazing and you can see it's very simple you don't need to do all of this like yourself you can just run this code and migrate it to your own database and it will be working perfectly now how do we actually make the queries how do we deal with this database i want to be able to um add a user to the database i want to be able to read from the table and i want to be able to update and delete right we want to i want to show you guys how to do this simple crud well we're going to do all of this in this index.ts so the first thing we want to do is just set up a very simple express server so i'm going to say import from express and i want to import the variable express like this and then down here at the bottom we're going to say const x app equal to express and then down here at the bottom i'm going to say after listen and i'm just going to listen to the port 3001 and let's just pass this function which is going to console.log um something like server running on port 3001 so very simple just a simple express server but we're going to create four different endpoints um for this and i'm going to cut the video really quick just i'm going to come back and all the endpoints will be done okay so as you can see over here i created the four endpoints necessary for a crud a pulse request which is going to be used to create and add stuff to our table the cat which reads the pot which updates and the delete which deletes right it's it's just giving me some errors right now because um because we're we declared this variable rack and res and we're not using it it's just some typescript error um that we're going to fix later on when we start actually using those variables but one thing that is important is you can see we're using typescript types this is just a preference you don't really need to do this but since we're using typescript i'm just going to put them right over here so now to actually use prisma in our app we need to import the prisma client so i'm going to come here at the top and i'm going to say import from the library at prismaclient and then we're going to import the actual variable called prismacline um it is a class as you can see and we're going to be using it to manipulate all the different tables that we have in our application i also want to come over here and say that i'm going to use um express dot json because um in this case specifically uh we want to be able to parse the logistic that comes to our application and we need to do this or else we're not going to be able to use json then we need to create an instance of this prismaclient so we'll just say const prisma or you can call it whatever you want equals to new prisma client like this and we're going to create an instance of this class and now we can use this variable to manipulate the table which is really nice so the first thing we want to do is we want to be able to use pre this prisma instance over here to add some sort of um user to our user table so inside of the post request over here we're going to first of all um get the data that you want to add to your table which is going to be sent through some json so to do that we're just going to say const equal to rect.body because we're going to get grab that from the body and we're going to grab the username and the password of the new user so username and password right and now with prisma there's a function you can run which will allow you to automatically add everything without actually running any sql this function is called create the create function so all we have to do is we're going to create this variable called user which is going to represent the user that we're trying to create and we're going to say equals to await so we have to make this asynchronous and whenever you're making whenever you're using prisma it is advised to always make your functions asynchronous and we're going to say await and then we're going to say prisma dot the name of the table you want to manipulate so user and then we're going to say dot create like this and we're going to pass the object inside of here which will contain the data in which we want to create right so i'm going to create uh we're going to pass the username and the username will be equal to username and we're going to pass a password which is going to be equal to password so when we save this um you can see that it's actually working one thing that is important as well is you need to import over here at the top the request and the response uh classes or else typescript will keep you keep giving you errors but basically all we have to do is this right here because this will automatically know that we're trying to insert this data into our user table and at the end i'm just going to return as json the user that we try to create and this is this is basically it for creating a user um now if you want to read or basically create an endpoint that is going to get all items from the table it's a lot easier just come over here to your endpoint so in this case it's just a simple get and we're going to create a variable called users so users or user list whatever you want and we're going to say oh wait um and then we're going to say the prisma.user. many so find many it is a function which allows you to get many different um rows from a table and in this case when we don't pass any conditions or anything like that it automatically gets everything and returns um everything inside of this user table so at the end let's just return back um the users variable that we received and this should return all the items in the table it's a lot easier than writing an sql statement um without like just writing sql without using any arm as you can see so with the putt request um we can do a lot of other things we want to be able to update some sort of piece of data in our table so in our case i want to update the username right imagine that you want to be able to update the username and from a user so to actually do that so to actually do that we need two pieces of information we need an identifier for which user we want to update and we want um the the the new value that we want to pass right so if you want to update the username we need to grab from the body an id and um a username because there are the new username so i'm going to say const equals direct.body and then we're going to grab an id the id of the user that we want to update and its new username so over here we can create a variable called updateduser so we're going to receive back the user with its new values and then we're going to set it equal to await uh prisma dot user and we're going to call the function update and update will update um some field in your apple in your table so how we actually structure this is we need to pass two objects inside of here um we need to pass a where object which contains like um which field we want to use as an identifier so in this case we want to say where we want to update a user where the id of the user is equal to the id that we passed in our body and then we need to pass a data which will be the new like the change that we want to make so i want to change the username to be equal to the new username and this is kind of a the structure of an update it's kind of weird but um it makes sense right we're just passing the identifier and the data that we want to change and this is basically it for the for the update request so i'm just going to return back uh the updated user like this and then finally for the delete um we're going to actually use params as you can see over here we're going to grab the id from the params and we are also going to make this async and inside of here to delete a user from your table it's as simple as um the the get request that we make we just come over here and we need to first grab the id that we're passing through the params so i'm going to say const id equals to rec.params.id like this and then all we have to do is create again a variable that is going to represent the user that we're trying to delete so deleted user and we're going to set this equal to await and we're going to call prisma.user because it's the user table dot delete right and inside of here we just have to pass an identifier so when i say an identifier i mean you gotta pass aware and some sort of field that we want to use as the identifier so in this case we're gonna say we wanna delete the user where the id is equal to the id that we grabbed from the params and as always at the end we're gonna res jason uh the deleted user so this is it for our actual crud you can see that we're getting a red line over here and the reason for that is because when you pass variables in their params um it actually grabs a pack as a string so and we declare that id is not a string it's an integer so just a side note if you want to if you have this problem just convert the id to a number um because you're going to get errors with that prisma is really good with typescript it alerts you of every single error that you might be making so um this is one of the great things from this library so you can see that this should be working and we're actually going to test if our api is working for actually adding stuff to our table if we are actually deleting them for updating them or if you're able to actually read them um the way we're going to do this is i'm going to use this really cool api tester that i use all the time called insomnia um you can download it down below um it is a really it is a replacement for a postman i know a lot of people use postman but basically you can see i made here all the four requests that we're going to be making on the get all users the create user the update username and the delete user and all of them are making the request to the localhost 3001 which is the port that we told our application to run at so one thing i want to do is i want to come to our package.json before we run and i want to be using node one right because i mentioned that i want to run with nodemon so to make node one run is we just have to come over here and pass the scripts tag and inside of here i'm gonna pass the script um let's call it dev start which means that we want to start our development environment and we're just going to say that it will basically run node 1 index ts which is the file that we are starting our application and now that we have this done let's run our api to run our api i'll just say again yarn dev start and it should start running as you can see now it says server running on port 3001 and we know that in our table we have no items right we have no user created here now let's try creating a user um in insomnia all you have to do is you have to put the type of your request so a post request the endpoint and then pass some sort of json if you want to i set this as json because that's what we're passing and i'm trying to create a username over a user over here with the username pedrotec and the password secret password so to make this work let's just click send and you can see that it returned okay it said it was successful let's test to see if this actually worked if i query our table now we have a user called page or tech and it has the secret password as a password right so it means it's working let's see if our get request our our query is working you can see it is it returns all the users in the table um let's see if our update username is working um over here you pass an id and a username um so the username over here you passed is what you want to change it to right now it is pedro tech let's change it to pedro right let's see if it works if i click this it said it was successful and if i we try to get this again now it's page rule and on page attack and let's try to delete the user to delete user you just have to make a delete request and pass the id of the user you want to delete so pedro like pedro attack or pedro has an id of one so we'll pass one over here at the top as the params and when we click send it should have deleted so now if i try to run this again it returns an empty array because there's nothing in our table as you can see over here so all of our requests have worked so far which is amazing and i hope you guys are getting value from this because um prisma is amazing it is a little more powerful than this basic crud now i want to show you guys another example which is basically being able to get a user by id so to do that we're going to create a get request over here really quick another get request but now we're going to call this trick this endpoint or this route um by id to identify that this is the we're trying to get some some user by its id so to do this we're going to need it to pass some sort of param so we're going to say that you need to pass the id as a parameter so over here we're going to grab this id from the parameter so const id equals to rec.params.id like this and with this we can now come over here and instead of saying find many you can guess that we can actually use a function called find unique which inside of here we can pass some sort of identifier that will only return one single user with that identifier so the identifier we want to use here is obviously the id so i'm going to say where id is equal to id so now this should return a single user so i'm going to call this user and it has to be with the id that we mentioned and again we need to convert this to number because it was a string but we defined a d to be a number or an integer so this should be working if we come to our insomnia let's create a new request over here um it should be get by id and it's a get request and i'm just going to copy the endpoint like this paste it over here and call it by id and then let's try to get um a new user right right now we don't have any users in our table um let's create pedro attack again um its id will be number two but let's create another user i'm gonna call it michael scott so the password will be scott and let's click send and let's get all the users in our table just so we see we have two users in our table and let's get michael so to get michael we just put the idea of michael so it's three and you can see that it returns michael if i want to get pedro i'll put two and it returns pedro tech which is amazing although we went over the basics i want to go over some of the more advanced stuff like how do you add many different um like users at the same time or maybe how can i update my user at the same time or even how do i create association between different models so for example if we want to be able to create many different users at the same time one thing that we can do is let's actually create here a post request another post request and call it something like um create many users i hate this name but like you guys get what i mean right over here we want to take into account not one username or not like one password we're actually going to take in as part of our body a list of objects and each object should contain a username and a password so we're just adding instead of just one we're adding a list of uh users right so to grab that we're going to grab a call the list something like user list like this and when we say create instead of saying create we'll say actually create many and it knows that automatically it should be accepting over here as part of the data a list so we can say user list over here and at the end let's just return the users i'll call users and just return it like this now if you come here to insomnia and we're going to create a new request it's going to be a post request let's call it create many users and it's going to be a post request right and the body will be a json uh adjacent like this so over here we're just going to put the same end point as the other post request but it should be create many users because that's what we called it right and in the json instead of passing an object like this we're going to pass a list of objects and each object will be in the format of a username and a password so this is what i'm going to be doing i'm going to pass an object like this let's create three of them right so you can see this is the format a list of users and the first one will be let's call it james the password is one two three second one is whatever actually i don't care i'm gonna put the password whatever as well this one i'm gonna call it leo and i'm gonna put the password um 789 something like this right we're also going to have to make all of this into a single object like this and the reason for that is because you still need to pass an object with a property and the property will be called user list and the user list will be an array so actually i need to make this like this and the formatting is kind of kind of weird but but when we click send you'll see that um it gives us a count of three which means we actually added three users at the same time and when we come to get all users we now should have all the users including um the ones that we just added so now we're getting into the last part and last section of this video we're going to teach you guys how to actually work with associations and creating different models and interconnecting them together so in this case let's create a very very simple example and let's actually create um let's think about it this way we have a table called users and imagine imagine that each user for some reason has a car right so each user can have multiple cars and we're going to create here a table for cars let's call it car and we want to be able to associate a car with a user right so each car must be owned by a user and we can have multiple cars were owned by the same user so we're going to be interconnecting them by putting fields in between them so that when we want to query the users and we want to know all the cards that exist that are from that user we can make that kind of relationship very easily so with prisma this is pretty simple honestly it's very simple um all you have to do is i'm actually going to create the car model up here for no reason i just prefer to have um i prefer to have the user model right at the bottom you guys don't need to do this but for a car we want to have an id obviously similar to this over here i'm just going to copy this and i'm going to paste it over here and then we're going to have a let's think about it this way what do we want for a car the model right it's just a string so we know which model it is maybe the year in which it was produced so that's an integer um it can also be a daytime i'm not going to focus on all the different uh types of uh like fields that you can add in in prisma you can check that out in the documentation but the important thing is we're gonna associate a user to this car so we're gonna pass over here a user field and we're gonna say that it is of type user and we're going to put a question mark because and we're going to say that it has a relation to uh the following fields uh in this case we're going to create over here right at the bottom we're going to association uh we actually want to create a field in each car which is the user id and this basically is a field representing the id of the user who owns this car so we're going to pass an end and we're going to say that the field that relates it it's this user id to the id or the field which is the reference right so we're gonna pass references over here and we're gonna say um id so this is kind of the idea right you're just passing um you're passing that you're creating a field called user and you're just saying that it relates to um the user model over here and we're trying to pass this field as uh the field that we want to relate to and this is the reference so to actually make this connection we also have to say that each user needs to have a core or multiple cars so in this case we want to allow each user to have multiple cars so we're going to say that it might have a field called cars and it's going to be an array of course so we just pass this empty bracket over here so this means that now we have a connection between both of them we have a table called user we have a table called car the car has an id a model a year and also the user in which it relates to and the idea of that user and each user will have a username and a password and a list of all the cars that they own and each car will include all the information that exists in the car table so this is kind of cool right so to actually make these changes occur because you can see that in our table over here this card table isn't even here because we actually need to run the migration again and the migration i'm going to cancel our our code that is running right now if you recall it is you need to run this code over here npx prisma migrate dash dash name init when i press this it's going to run everything um and it's going to generate a new migration to our table and when we refresh this over here you'll see that now we have a card table we also have another migration entry in our migration table and the card table is pretty interesting you can see that it has an id a model a year and the user id and now if we go to the user table you'll see that if we want to query all the users or all the like if we want to grab for example over here in our index.cs right um let me come over here if we want to grab all the users that exist and together with the list of users that we have we want to query the cards that they have as well it's actually pretty simple all we have to do is we need to add some cards to to this table over here and i'm going to do that pretty simple i'm actually going to just create an endpoint over here which is going to be a create car endpoint i'm going to create it right over here i'm just going to copy the code that we created i'm going to create a create many endpoint which is uh so we can create many different cards at the same time let's call it create many cars and we're going to use the car table now instead of the user table and let's grab a car list and let's just re pass it as a data and this will be cars and we're just going to return them back now that we have this endpoint we can actually run it in insomnia i'm just going to create i'm actually going to double click duplicate this one over here to and call it create many cars and instead of being create many users we're going to say create many cars and instead of passing or accidentally accidentally pass the correct information uh let me just run this again and let's come over here to insomnia now instead of passing a user list we need to pass a car list like this right because we called it a a car list uh we said that this is what we want to pass and this in our body and we want to pass for each car we need to pass a model a year and a user id so let's just pass uh a model over here let's call it a tesla i know that that's that's a brand not a model but i don't care um and then the year let's pass 2091 to 191 whatever and the user id let's say that pedro tax or pedro attack owns this task list so let's say uh the idea will be one right because pedro attack is one i guess let me just check to see if it's i know it's actually two but uh so let's actually change that let's make it two and then we wanna add another car so i'm gonna copy all of this um let's make this also for pedro tech and let me let me make this a ferrari and the year was 2931 it's also from pedro and the final one is not a it's a i don't know let's let's make it a honda uh it's from 1987 and it is for michael scott which is user number three so let's pass it over here when we click send it should create all the users actually i got an error because we passed the ear as a string but it should be a number and i completely forgot this so let me just remove this things over here and it should now be a number and let me run my code again um so we're running our server again and you can see that if i click send now it actually counted three so it means it should be like our table should be updated if i refresh our car list it now has three cars beautiful so now if we want to query um all users and include um the cards that each user have we actually need to come to our request so over here you can see find many and we can pass a property inside of this which is the include property and we need to pass the name of the field that we added so the field that we added in the user is cars so we need to say that we want to include cars and they need to be true so we're seeing that including cars is equal to true which means that whenever we query all the users we also want to include the cards that each user has so when we come to insomnia and we make this request again it now includes for the users who have who has cars the individual cars that they have so for example pager tag has two cars michael's car has one but um all the other ones don't have one so it doesn't include so this is a very brief overview of associations and relations using prisma but you can see it's very easy um it is very self-explanatory straightforward which it's a bit different from other libraries i know doing it in typeform is a bit harder um sequence it's pretty similar to prisma but overall i love my experiment my experience with prisma i am a big fan of typeform for typescript and sqlize for just javascript in general but maybe in my next project i'll probably be using prisma just because it's a new technology and i really like how it looks i really like um the flow of a project when when using prisma and i've been using typeform for a long time so maybe it's time for a change so that's that's kind of my opinion on the on the library if you enjoyed the video leave a like down below and comment what you want to see next subscribe because i'm posting three times a week and it's been a lot of work but i love the support that i get from you guys so if you guys can leave a like help with my push more people i would really appreciate that and yeah that's basically it i hope you guys enjoyed it and i see you guys next time
Info
Channel: PedroTech
Views: 3,105
Rating: 4.9663863 out of 5
Keywords: computer science, crud, css, databases, javascript, mysql, nodejs, programming, react tutorial, reactjs, reactjs beginner, reactjs tutorial, typescript, react js crash course, react js, node js, express js, pedrotech, traversy media, traversymedia, clever programmer, tech with tim, freecodecamp, deved, pedro tech, prisma, prisma.io, prisma tutorial, orm tutorial, prisma orm, typescript tutorial, prisma nodejs, prisma mysql tutorial, prisma mysql example, computer science for beginners
Id: E37-33M6Ypk
Channel Id: undefined
Length: 38min 47sec (2327 seconds)
Published: Mon May 31 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.