2024-01-07
Goal
Learn how to upload more than 100 records via the shell
Notes
Last time I left off, I wanted to learn how to Django Bulk Upload to upload a variety of data features (including fighter cosmetics and spirit fighter stats). I was still running into the bizzare "non-unique id" error that I was last time.
I ended up screwing up my Database Migrations and needed to reset my SQLlite database. That's not a big deal here because I had no important data in the app (with the exception of the Django Superuser) which was easy to recreate using
python manage.py createsuperuser
I still wanted to use some kind of bulk upload system, so I referenced ChatGPT for help.
It wasn't helpful, but I was able to increase the batch size to 2500
(since there are only about ~2200 fighters I have data for).
Bizarrely enough, this approach worked. Instead of using the batching procedure, I therefore decided to just use the following script:
from fighters.models import SpiritFighter
import json
with open(r"C:\Users\Billy\Documents\HitHub\bulk_uploads\Fighters\spirit_fighter_metadata.json", "r") as f:
spirit_fighter_data = json.load(f)
# Clear the current table
SpiritFighter.objects.all().delete()
# Build up the objects data
objs = []
for fighter_id, fighter_data in spirit_fighter_data.items():
objs.append(SpiritFighter(
ufc_id = fighter_id,
height = fighter_data["height"],
weight = fighter_data["weight"],
stance = fighter_data["stance"],
first_name = fighter_data["first_name"],
last_name = fighter_data["last_name"],
nickname = fighter_data["nickname"],
date_of_birth = fighter_data["DOB"],
w = fighter_data["w"],
l = fighter_data["l"],
d = fighter_data["d"],
stats = fighter_data["stats"],
))
SpiritFighter.objects.bulk_create(objs)
to simply bulk create all of the objects at once. This gave no issues and when I tried removing the table clear at the beginning (SpiritFighter.objects.all().delete()
) it was still effective. I must have been entering it in an incorrect way or maybe somehow there was some kind of issue with Asynchronous allocation of unique Primary Keys.
Designing the Bets Table
This is the tricky one that I've been putting off for a while. I now have the key components for the rest of the app and know how to bulk upload records (which will become important later on for actually populating my database with tables.). The last model I'll need to design will be for the Bets App. I'm thinking that
- Bets will need to be placed in advance, so they should be tied to Upcoming Fights in the Fights App via that fight's
id
- Some bets will be reliant on different conditionals that will need to reference the behavior of the individual fighter (i.e tied to a
fighter_id
from the Fights App) - I want to implement two bets for sure,
moneyline
andtotals
bets, howeverprop
bets will be the most fun. Either way a the Bets App should have a unique modelmoneyline
- Which fighter will wintotals
- How long will the fight last
I wanted to create something dynamic that had a basic structure that all other bets conditionals could be stacked on top of. In this case ChatGPT actually had a great solution that involved building a general Bet
class that other bet types could be stacked on top of. It included the class Meta
field with abstract = True
, which was so that a Django wouldn't build a table for the base bet class but instead will build one for other bet types (i.e moneyline
and totals
bets).
With the help of ChatGPT I was able to create these classes and generate the Bets table. Nice! Now I'll be able to create additional prop bets (i.e touchgloves, makes weight, gets murdered, etc.) easily in the future.
Designing the CustomUser
That was a hell of a journey but I finally have the bare bones of what I need to get the app off the ground on the data side. Of course we can make adjustments as needed (adding or removing features). I found out I was on the old fixed-routes
branch when I used the
git branch --show-current
command. The last thing I wanted to do was adjust the Accounts App to use a custom user model. Thankfully this is covered in Django For Professionals on pg 56 so following the instructions was easy enough. The author notes just how important it is to create a custom user model since everything else is tied into the app.
To do this I needed to create a CustomUser
model in the Accounts App based on Django's built in AbstractUser
model. Then I needed to add that into my project's hithub/settings.py
file and set the default user to
AUTH_USER_MODEL = "accounts.CustomUser"
so that Django recognizes it as the default user.
Thankfully I did this before any important info was loaded into the app because there were some serious migration conflicts with my test superuser! Thankfully I was able to wipe the database by deleting SQLlite and the non-initial migrations of each app. I also added the coin
attribute to this custom user to allow our users to use money.
Pushing Changes to GitHub
Now that all of the Database stuff was up and ready to go and my custom users were running all I needed to do was push it to GitHub. I checked out a Git Branch called completed-db-construction
via the following command and pushed to GitHub:
git checkout -b completed-db-construction
git add .
git commit -m "my inspiring message"
git push
Then I pushed these changes to Staging by merging it with the dev
branch.
Finally I merged dev
to main
and pulled it back into my local project with git pull
.
Also last minute I decided to declare the currency to be hitcoin
. That was a very important last minute change.
Results
- Finished developing the Database needed for the HitHub App
- Completed functionality to handle basic bets within the Bets App
- Added a
sponsor
where a user can sponsor a fighter in the Fighters App- This will come in handy if I decide to assign users their own fighter to take care of in the future
- Implemented a
CustomUser
model for the Accounts App- Now users have 1k starting
hitcoin
- Now users have 1k starting
Next Time
- Learn how to bulk upload other attributes
- Learn how to bulk upload cosmetics
- Learn how to create fighters in the database based on the data we've bulk uploaded
- It may make sense to use AWS Lambda functions to execute the actual fights. Therefore it might make a sense to learn how to integrate the Django API
- Start developing the Frontend / surfacing data to the Front end
- Write Unit Tests D: