Skip to main content

Piccolo Postgres integration for Red

Project description

red-postgres

Piccolo Postgres integration for Red-DiscordBot, although it could be used with any dpy bot as an easy wrapper for making postgres with cogs more modular.

PyPi Pythons

Postgres Red-DiscordBot

black license

Install

pip install red-postgres

File structure for using with cogs

cog-folder/
    ├── db/
    │   ├── migrations/
    │   ├── piccolo_conf.py
    │   ├── piccolo_app.py
    │   ├── tables.py
    ├── __init__.py
    ├── cog.py

SCHEMA

Cog Usage

import asyncio
from pathlib import Path

from piccolo.engine.postgres import PostgresEngine
from redbot.core import commands
from redbot.core.bot import Red

from red_postgres import register_cog
from .db.tables import MyTable


class PiccoloTemplate(commands.Cog):
    def __init__(self, bot: Red, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.bot = bot
        self.db: PostgresEngine = None

    async def cog_load(self):
        asyncio.create_task(self.setup())

    async def setup(self):
        await self.bot.wait_until_red_ready()
        config = await self.bot.get_shared_api_tokens("postgres")
        self.db = await register_cog(self, config, [MyTable])

    async def cog_unload(self):
        if self.db:
            self.db.pool.terminate()

The config for piccolo should have the following keys:

{
  "database": "postgres",  # Replace with your maintenance database
  "host": "127.0.0.1",  # Replace with your host
  "port": "5432",  # Replace with your port
  "user": "postgres",  # Replace with your user
  "password": "postgres"  # Replace with your password
}

Note: database name in your config should normally be the default "postgres", this library will automatically handle connecting your cogs to their own database

The register method connects to the database specified in config, creates the a new database with the name of the registering cog, registers any tables, runs any migrations, sets the new engine object to all tables, and returns the raw engine object.

  • The name of the database will be the the name of the cog's folder, not the name of the main cog.py file

You can then use your piccolo table methods like so:

count = await MyTable.count()
or
objects = await MyTable.objects().where(MyTable.text == "Hello World")

The engine associated with your tables after registering the cog is connected to the database named the same as the cog that registered them, thus using this integration with multiple cogs will not interfere, as each cog will create its own database.

  • If your cog's folder name is MyCog then the database will be named mycog

Piccolo Configuration Files

Your piccolo configuration files must be setup like so. This is really only used for migrations.

  • When migrations are run, the os environment variables are mocked in subprocess, so there should be no conflicts

piccolo_conf.py

import os

from piccolo.conf.apps import AppRegistry
from piccolo.engine.postgres import PostgresEngine

DB = PostgresEngine(
    config={
        "database": os.environ.get("POSTGRES_DATABASE"),
        "user": os.environ.get("POSTGRES_USER"),
        "password": os.environ.get("POSTGRES_PASSWORD"),
        "host": os.environ.get("POSTGRES_HOST"),
        "port": os.environ.get("POSTGRES_PORT"),
    }
)


APP_REGISTRY = AppRegistry(apps=["db.piccolo_app"])

piccolo_app.py

import os

from piccolo.conf.apps import AppConfig, table_finder

CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))

APP_CONFIG = AppConfig(
    app_name="cogname",  # Replace with your cog name
    table_classes=table_finder(["db.tables"]),
    migrations_folder_path=os.path.join(CURRENT_DIRECTORY, "migrations"),
)

for table_classes add in the list of tables you're using

Local development and making migrations

Handing migrations is up to you, but one way to do it is to make migrations locally like so:

First make an .env file in the root of your cog's folder.

POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DATABASE=postgres

Then create a build.py file in your cog folder.

import asyncio
import os
from pathlib import Path
from dotenv import load_dotenv
from engine import engine

load_dotenv()

config = {
    "user": os.environ.get("POSTGRES_USER"),
    "password": os.environ.get("POSTGRES_PASSWORD"),
    "database": os.environ.get("POSTGRES_DATABASE"),
    "host": os.environ.get("POSTGRES_HOST"),
    "port": os.environ.get("POSTGRES_PORT"),
}

root = Path(__file__).parent


async def main():
    created = await engine.ensure_database_exists(root, config)
    print(f"Database created: {created}")
    description = input("Enter a description for the migration: ")
    print(await engine.create_migrations(root, config, True, description.replace('"', "")))
    print(await engine.run_migrations(root, config, True))


if __name__ == "__main__":
    asyncio.run(main())

You would have a similar file in the root of each of your cog folders, here you would create the migrations to include in your cog folder for users to run when they load up the cog.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

red-postgres-0.5.1.tar.gz (9.0 kB view details)

Uploaded Source

File details

Details for the file red-postgres-0.5.1.tar.gz.

File metadata

  • Download URL: red-postgres-0.5.1.tar.gz
  • Upload date:
  • Size: 9.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.11.2

File hashes

Hashes for red-postgres-0.5.1.tar.gz
Algorithm Hash digest
SHA256 d1c8d99cc9032ac814a2d3f5b969df160a995d662837e0ae4fed3392b33eb523
MD5 5ff30453e87e5b776b07e731e2b076a4
BLAKE2b-256 0040541f60caef4f407960822d15e878b99e31d7f3eed4d72d3cd9d7614f72ad

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page