ponyorm / pony

Pony Object Relational Mapper
Apache License 2.0
3.58k stars 242 forks source link

Base Pony Model for multiple databases #697

Open peterhorvat opened 6 months ago

peterhorvat commented 6 months ago

I have a project with many Pony Models where all of them share some fields:

uuid = PrimaryKey(str)
deleted = Optional(bool, sql_default=False)
created_at = Required(datetime, sql_default=get_now(settings.DB_PROVIDER))
updated_at = Required(datetime, sql_default=get_now(settings.DB_PROVIDER))

I want to create a BasePonyModel like:

class BasePonyModel:
    uuid = PrimaryKey(str)
    deleted = Optional(bool, sql_default=False)
    created_at = Required(datetime, sql_default= get_now(settings.DB_PROVIDER))
    updated_at = Required(datetime, sql_default= get_now(settings.DB_PROVIDER))

I would then use that Base model like:

class SomePonyModel(BasePonyModel(table='table_name', database=db)):
   name = Optional(str)
   description = Optional(str)
   ...

The problem is that I cannot manage to get it working in a generic way so I could use the same base model for multiple models. I tried overriding init and new, but I had no success doing it. Since I have multiple databases I have to pass in the db: Database object to make it work. If you have any clue how this can be done (if it can be done) please point me in the right direction. I think this "BasePonyModel" logic would help a lot of people to clean up their code.

peterhorvat commented 6 months ago

I tried the following and it only works for one model but if I use it on multiple models I get pony.orm.core.ERDiagramError: Entity BasePonyModel already exists

def setup_base_pony(database: Database, table: str):
    from pony.orm import Database, PrimaryKey, Required, Optional
    from datetime import datetime

    class BasePonyModel(database.Entity):
        _table_ = table

        uuid = PrimaryKey(str)
        deleted = Optional(bool, sql_default=False)
        created_at = Required(datetime, sql_default=get_now(settings.DB_PROVIDER))
        updated_at = Required(datetime, sql_default=get_now(settings.DB_PROVIDER))
    return BasePonyModel

# USAGE 
from pony.orm import Database

db = Database()
class SomePonyModel(setup_base_pony(database=db, table='some_pony'):
JoshYuJump commented 6 months ago

Probably the same issue as this: https://github.com/ponyorm/pony/issues/104