2009-12-27 60 views
1

您好我有一個表中3NF形式SQLAlchemy的查找表

ftype_table = Table(
    'FTYPE', 
    Column('ftypeid', Integer, primary_key=True), 
    Column('typename', String(50)), 
    base.metadata, 
    schema='TEMP') 
file_table = Table(
    'FILE', 
    base.metadata, 
    Column('fileid', Integer, primary_key=True), 
    Column('datatypeid', Integer, ForeignKey(ftype_table.c.datatypeid)), 
    Column('size', Integer), 
    schema='TEMP')                 

和映射器

class File(object): pass 
class FileType(object): pass 
mapper(File, file_table, properties={'filetype': relation(FileType)}) 
mapper(FileType, file_table) 

假設F-類表包含1:TXT 2:AVI 3:PPT

我會喜歡做的是如下,如果我創建一個文件對象是這樣的:

file=File() 
file.size=10 
file.filetype= FileType('PPT') 
Session.save(file) 
Session.flush() 

是該文件表中包含的fileid:XXX,大小:10,datatypeid:3

不幸的條目被添加到文件類型表,這個ID被傳播到文件表。

有一個聰明的辦法做到實現上面的SQLAlchemy不用其他需要做的文件類型表的查詢,看是否該條目存在或不

感謝

回答

0

由於declarative_base和zzzeek代碼不與SQLAlchemy的0.4工作,我 用下面的緩存,以便新的對象也留下獨特的,如果它們不存在在DB文件類型的

class FileTypeCache(dict): 
    def __missing__(self, key): 
     try: 
      obj = self[key] = Session.query(FileType).filter_by(typename=key).one() 
      return obj 
     except InvalidRequestError: 
      return obj=self[key]= FileType(key) 
      return obj 

覆蓋EQ

class FileType(object): 
    def __init__(self, typename) 
     self.typename=typename 
    def __eq__(self): 
     if isinstance(other, FileType): 
      return self.typename == other.typename 
     else: 
      return False 
0

只需創建文件類型的緩存對象,以便數據庫查找僅在第一次使用給定文件類型時發生:

 
class FileTypeCache(dict): 
    def __missing__(self, key): 
     obj = self[key] = Session.query(FileType).filter_by(typename=key).one() 
     return obj 

filetype_cache = FileTypeCache() 

file=File() 
file.size=10 
file.filetype= filetype_cache['PPT'] 

應該可以工作,模仿輸入錯誤。

+0

這是正確的方向,但1)'__missing__'不會用新的值更新緩存,2)手動緩存的對象應小心處理,當他們從會議中清除。 – 2009-12-27 17:39:58

+0

糟糕,修復了緩存邏輯。感謝您的注意。 – 2009-12-28 06:45:31

2

UniqueObject配方是標準答案:http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject。我們的想法是使用兩種__metaclass__.call()File.__new__()返回已經存在的對象,從數據庫或從緩存中(初始數據庫查找,如果對象是不存在覆蓋的File創作,顯然是不可避免的,除非有圍繞構建MySQL的REPLACE被使用)。

編輯:因爲我一直在使用的食譜,我已經改寫了獨特的配方對象要更便攜和更新的0.5/0.6。

+0

看起來不錯。 不幸的是我使用db2並堅持使用sqlalchemy 0.4.0是否有0.4.0版本 – locojay 2009-12-29 19:53:17