/ home / posts / Make your own DB

So you want to make your own Postgres compatible database but you don’t want to drown in types with Rust or Go? Now, you can write your own database using Python:

from postgres_wire import create_server, Handler
from pydantic import BaseModel

class SomeObject(BaseModel):
  foo: str
  bar: int

class SomeHandler(Handler):
  def query(self, sql):
    return [SomeObject(foo="wow", bar=12), SomeObject(foo="woah", bar=21)]

serve = create_server(SomeHandler)
serve() # You can now connect with `psql postgresql://user:pass@localhost:5432`

What the above does is define a database server that will always return the same records regardless of the SQL query but the schema is autodetermined from the Pydantic models. And, from the perspective of the Postgres client, it’s a legitimate server!

$ psql postgresql://user:password@localhost:5432/db
psql (14.19 (Homebrew), server 0.0.0)
Type "help" for help.

db=> SELECT t;
  foo   | bar
--------+-----
 'wow'  |  12
 'woah' |  21
(2 rows)

db=>

But how would it look if we wanted to turn something into a database and not have static values forever? For cases where you want to dynamically assemble the returned rows:

from postgres_wire import create_server, Handler
from pydantic import create_model

class CustomHandler(Handler):
  def query(self, sql):
    CustomObject = create_model("CustomObject", bazinga=str, wahoo=(int, 123))
    return [CustomObject(bazinga="wow"), CustomObject(bazinga="wow again")]

serve = create_server(CustomHandler)
serve()

Which then gives the below:

$ psql postgresql://user:password@localhost:5432/db
psql (14.19 (Homebrew), server 0.0.0)
Type "help" for help.

yev=> SELECT t;
   bazinga   | wahoo 
-------------+-------
 'wow'       |   123
 'wow again' |   123
(2 rows)

yev=>