2016-12-15 62 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會自動添加此列,但是如果有可能您僅導入basic模塊Pony不會知道ExtendedPerson子類的存在,並且不會自動將該屬性添加到實體定義中。

另一個用例是當您購買由其他開發人員編寫的第三方模塊並希望擴展其功能時。對於這種情況,我們計劃在稍後定義的實體中添加定義關係的可能性。當我們添加這些功能,您將能夠只是Passport實體定義關係,示例語法是:

類Person(db.Entity): 名=必需(STR)

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

現在小馬沒有這樣的功能,但我們可以在不久的將來添加它

+0

謝謝亞歷山大!我會看看繼承。功能的擴展似乎最適合我的用例。展望PonyORM的未來。 –

相關問題