Libove Blog

Personal Blog about anything - mostly programming, cooking and random thoughts

Veganer Parmesan

Prep Time:


  • 200g Cashews
  • 60g Hefeflocken
  • 1 TL Knoblauchpulver
  • 1 TL Salz


Alle Zutaten in einen Standmixer geben und solange zerkleinern bisam ein feines Pulver hat. Sobald die richtige Konsistenz erreicht ist, "fließt" der Parmesan nicht mehr richtig beim mixen und leicht klumpig wird.

Pink Donut

Pink Donut

3D Printed Toy Screws

After seeing how I put a child barrier together my daughter is obsessed with screws. She will try to turn any screw she can find, using any item barely resembling a screwdriver. Naturally, she got her own set of tools :).

A Block with 2 screws. In front of it lie a toy screwdriver and wrench

As the set didn't include any screws I've decided to print some for her. The screws are compatible with the wrench and screwdriver of the "klein Bosch Work-Box". The holes of the block are loose enough to easily screw in the bolts.

I've used Blender to create these. For my first try I've created my own screw using the "Screw" modifier applied to a triangle. This worked okay, but the resulting screw was too loose and would just slip into the hole. For the next try I used the plugin "Bolt Factory" to create the screw part and only kept my previously designed head.

Things I've learned:

  • A 6-vertices circle with 18mm circumference is not the same as a 18mm screw head. The "18mm" refers to the distance between to edges, not two vertices.
  • 3D printed screw holes need a lot more "room". Simply scaling by the X and Y axis worked for my "triangle screw" but not the generated screw. Instead I had to thicken and thin the bands of the screw.

How to modify a screw to be used as a hole

All files can be used under the CC-BY 4.0 License.



Green Paprika + Onion Pizza

Green Paprika + Onion Pizza

Materialized Views in PostgreSQL

At my hobby project Podcast de facto Standard I ran into problems querying the required data to render the report pages. My first fix for this was to query and process all data (for all reports) once per day and to store the results as one big JSON object in an additional table. This worked well until the server was running out of memory because too much data had to be loaded from the database to be processed in python.

I generally try to avoid database specific feature for as long as possible in my projects. Ideally I'm able to use SQLite in local development and automated testing and only start using Postgres in the testing and production environment. This works great with abstraction layers such as SQLAlchemy and Django and allows me to postpone the decision for a specific database system for as long as possible. As a nice bonus it keeps the testing setup very simple as I can simple use an in memory SQLite.

The growing memory requirements were the point where I had to choose a specific database. As I use PostgreSQL virtually always in production systems I looked into the options it provided to optimize my queries.

The main problems where cause by the episode data, a ~9 GB table with +11 million rows. I already had indexes in place but the queries for the audio properties of podcasts still took +1 minute per plot. This meant that "live" queries where no longer possible and I needed a solution to store (partial) results.

I've chosen to use materialized views as they are a great fit for my problems. The data presented on the page doesn't have to be updated with every newly analyzed audio file. It is sufficient to get an update once per day (even once per week would be fine). The transformations required can easily be done in SQL.

Materialized views behave almost like a regular table, but you cannot directly create or update rows in the table. Instead the content is created from an SQL statement, executed once on creation or upon refreshing the view.

Creating a materialized view is simple:

create materialized view pub_hist 
select date(publishing_date), count(*)
from episode e
group by date(publishing_date)

This command executes the selection query and stores the result in the view pub_hist. Afterwards you can simply query from this view:

select *
from pub_hist
where "date" < now()

Other than normal views the content of the materialized view is not updated automatically. Instead you have to trigger a refresh, which will reevaluate the defined query and store the result:


To refresh the views I simply run a daily (celery) job, which calls the refresh command for all views.


Servings: Für 4 Pizzen , Prep Time:


  • 1 Dose Tomatenstücke
  • 2 Knoblauchzehen
  • 1 EL Olivenöl
  • Oregano
  • Thymian
  • Salz und Zucker
  • Optional: 1/2 Chili (getrocknet oder frisch)


  • Knoblauch schälen und grob hacken
  • Auf mittlerer Hitze in einem kleinen Topf Olivenöl und Knoblauch erhitzen
  • Unter ständigem rühren den Knoblauch im Öl 2-3 Minuten garen. Der Knoblauch darf nicht braun werden
    • Chilis ebenfalls mitgaren falls gewollt
  • Tomatenstücke dazugeben und zum köcheln bringen
  • Kräuter und eine Prise Salz und Zucker hinzugeben
  • Herd auf niedrige Hitze drehen und mit halb aufgelegtem Deckel für 20-30 Minuten einköcheln lassen
  • Mit dem Pürierstab zur gewollten Konsistenz zerkleinern
  • Heiß in ein verschließbarers Glas füllen, kann mindestens eine Woche im Kühlschrank gelagert werden

Rezept für Pizzateig

Schnelle Pizzasauce

Servings: Für eine Pizza , Prep Time:


  • 3-4 EL Passata
  • 1/2 EL Olivenöl
  • 1 TL Oregano
  • Prise Salz
  • Prise Zucker


All Zutaten zusammengeben, gut mischen und direkt auf die Pizza. So einfach!

Wer mag kann auch noch etwas Knoblauchpulver geben. Für eine pikante Soße einfach ein bisschen Chili aus der Mühle dazu.