2016-12-15 4 views
1

Я хочу разделить определение класса сущности, т. Е. Добавить столбцы после того, как я изначально объявил класс (но до того, как я сгенерировал отображение). Это вообще возможно?В PonyORM можно разделить определение объекта?

Я уменьшил свою проблему до этого примера кода ниже. Он генерирует pony.orm.core.ERDiagramError: Reverse attribute for Passport.person not found для генерации отображения. Когда я положил passport = Optional("Passport") в определение класса, все работает, но я хочу разбить паспорт часть от чистого человек часть.

Я понимаю, что ответ может быть просто: «Извините, Дэйв. Боюсь, я не могу этого сделать».

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 


from pony.orm import * 


db = Database() 

### PART 1: Person ### 
class Person(db.Entity): 
    id = PrimaryKey(int, auto=True) 


### PART 2: Passport (belonging to a Person) ### 
Person.passport = Optional("Passport") 

class Passport(db.Entity): 
    person = Required("Person") 


db.bind("sqlite", ":memory:") 
db.generate_mapping(create_tables=True) 
+0

В конце концов, я трачу гораздо больше времени на то, чтобы справиться с реальной проблемой, чтобы добраться до этого короткого примера, чем фактически решить проблему. Опять же выясняется, что истинная проблема доставит вам долгий путь. –

+0

Привет, Берт! Почему вы хотите это сделать, какова ваша мотивация? –

+0

Привет, Александр! Я пытаюсь написать модульное приложение, то есть приложение, из которого у меня может быть «базовая» версия и версия с добавленными дополнительными модулями. Итак, в этом фиктивном примере вы можете управлять людьми (базовыми) и тем, где вы также можете зарегистрировать паспорта (с дополнительным паспортным модулем). –

ответ

0

После ознакомления с исходным кодом PonyORM и некоторых проб и ошибок я нашел то, что я могу сделать, чтобы заставить его работать. Хотя я не уверен, что это официальный и если все необходимо. Поэтому я не уверен, что это будет работать в будущих версиях.

Код

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 


from pony.orm import * 


db = Database() 

### PART 1: Person ### 
class Person(db.Entity): 
    id = PrimaryKey(int, auto=True) 
    name = Required(unicode) 


### PART 2: Passport (belonging to a Person) ### 
extra_column = Optional("Passport", reverse='person') 
extra_column._init_(Person, 'passport') 
Person._attrs_.append(extra_column) 
Person._new_attrs_.append(extra_column) 
Person._adict_['passport'] = extra_column 
Person.passport = extra_column 


class Passport(db.Entity): 
    person = Required("Person", reverse='passport') 


db.bind("sqlite", ":memory:") 
db.generate_mapping(create_tables=True) 
1

Я думаю, что ответ зависит от сценария использования. В своем комментарии вы сказали, что хотите иметь «базовую» и «расширенную» версию своего приложения. В этом случае я предлагаю использовать наследование лица:

########## basic.py ########## 
from pony.orm import * 

db = Database() 

class Person(db.Entity): 
    name = Required(str) 
    contacts = Set("Contact") 
    classtype = Discriminator(str) 

class Contact(db.Entity): 
    person = Required(Person) 
    type = Required(str) 
    value = Required(str) 

########## advanced.py ########## 
from basic import * 

class ExtendedPerson(Person): 
    passport = Optional("Passport") 

class Passport(db.Entity): 
    person = Required(ExtendedPerson) 
    code = Required(str, unique=True) 

########## main.py ########## 
from advanced import * 
import settings 

db.bind('postgres', **settings.db_params) 
db.generate_mapping(create_tables=True) 

with db_session: 
    john = ExtendedPerson(name='John') 
    p = Passport(person=john, code='123-456') 

Столбец Discriminator столбец система, которая используется для наследования. Pony сохраняет все подклассы в одной и той же таблице и определяет подкласс конкретного экземпляра, смотрящего на значение этого столбца. Обычно Pony добавляет этот столбец автоматически, но если возможно, что вы иногда будете импортировать только basic модуль Pony не будет знать о существовании подкласса ExtendedPerson и не будет автоматически добавлять этот атрибут в определение сущности.

Другой вариант использования - когда вы берете сторонний модуль, который был написан другим разработчиком и хотите расширить его функциональность. В этом случае мы планируем добавить возможность определять отношение только в одном сущности, которые определены позже. Когда мы добавим такую ​​функциональность, вы будете иметь возможность определить отношение только в Passport сущности, пример синтаксиса:

класс Person (db.Entity): имя = Обязательно (ул)

class Passport(db.Entity): 
    person = Required("Person", 
     reverse='passport', reverse_attr=Optional("Passport")) 
    code = Required(str, unique=True) 

Прямо сейчас у Pony нет такой функциональности, но мы можем добавить ее в ближайшее время.

+0

Спасибо, Александр! Я посмотрю на наследство. Расширение функциональности, по-видимому, больше подходит для моего использования. С нетерпением ждем будущего PonyORM. –

Смежные вопросы