Как мне перечислить все типы сущностей из объекта БД? - PullRequest
1 голос
/ 30 апреля 2019

Я использую новейшую пониму на Python 3.6.

Я хочу сделать некоторые обезьяны-патчи для классов сущностей, созданных на другом этапе (чтобы добавить вычисляемые поля).

Есть ли шанс, что я смогу получить список типов сущностей, доступных из объекта db?

В моем файле models.py:

from pony.orm import *
db = Database()

class OneEntity(db.Entity):
    id = PrimaryKey(int, auto=True)
    nom = Required(str)

class AnotherEntity(db.Entity):
    id = PrimaryKey(int, auto=True)
    someprop = Required(str)

В другом файле:

from models import *
db.bind(provider='sqlite', filename = 'test.db', create_db = True)
db.generate_mapping(create_tables = True)

def say_hello():
    """ some dummy proc to monkey patch onto entity classes"""
    print("hello")

#This works, but isn't workable for my use case (too many entity classes)
OneEntity.monkey_patched_method = say_hello


#And here I'd like to have the ability to list entity classes programmatically

for Entity in some_code_that_i_dont_know :
    Entity.new_method = say_hello

Ответы [ 3 ]

1 голос
/ 30 апреля 2019

Вы можете получить подклассы Entity, используя метод __subclasses__.

Этот пример взят из Flask SQLAlchemy. Ваши результаты должны быть похожи:

>>> db.Model.__subclasses__()                                                                                                                               
[myapp.models.User,
 myapp.models.Organization,
 myapp.models.Customer,
 myapp.models.Address,
 ...
]

В вашем коде вы должны сделать следующее:

for Entity in db.Entity.__subclasses__():
    Entity.new_method = say_hello
1 голос
/ 01 мая 2019

В PonyORM Database объект имеет свойство entities, которое является указанием всех связанных сущностей:

for entity_name, entity_cls in db.entities.items():
    print(entity_name)
0 голосов
/ 30 апреля 2019

Это не относится к Pony, но вы можете использовать inspect.getmembers для этого:

import inspect
import models


for name, attr in inspect.getmembers(models):
    if inspect.isclass(attr) and issubclass(attr, db.Entity:
        models.__dict__[name].new_method = say_hello

В основном это будет проходить через все атрибуты модуля models и добавлять new_method к любым db.Entity подклассам, с которыми он сталкивается.

...