2014-12-04 29 views
0

我有一個使用SQLAlchemy反映表時想使用的列定義字典,但如果列實際存在於數據庫中,我只想使用每個列定義。例如:如何重寫反射列只有它存在使用SQLAlchemy?

TABLE_DEFAULTS = { 
    'my_table': { 
     'my_column': Column(String), 
     'other_column': Column(String), 
     'third_column': Column(String, default='Sample') 
    } 
} 

比方說,我反映my_table,它恰巧有third_columnfourth_column。我有一個默認值third_column,所以我想使用它。由於我沒有默認fourth_column,所以我想使用反射所產生的列。以下僞代碼顯示如何使用默認列生成模型類。

tbl_name = 'my_table' 
cls_dict = dict(
    __table_args__={'autoload': True, 
        'autoload_with': engine}, 
    __tablename__ = tbl_name 
) 
if tbl_name in TABLE_DEFAULTS: 
    # TODO: Only want to add the default columns if they actually exist in db 
    cls_dict.update(TABLE_DEFAULTS[tbl_name]) 

# Unfortunately, MyModel will have attributes for my_column and other_column 
# even though they don't exist 
MyModel = type(tbl_name, Base, cls_dict) 

解決我的問題,我覺得我有做自動加載,基本檢查兩次數據庫之前檢查數據庫。或者可能更好,只是不要自動加載,而是根據早期檢查創建列。這是做這件事的正確方法,還是有一種更簡單的方法?我希望也許在API中會有一些東西來覆蓋只有在數據庫中存在的列定義。

回答

1

假設每個應用程序只進行一次反射,但是我沒有看到首先檢查數據庫的問題,只是爲了獲取所需表的列。實際上,您可以從原始TABLE_DEFAULTS創建一個更新字典的例程,其餘代碼無需更改即可正常工作。

另一種方法是聽取column_reflect事件並根據需要修改列。但是,在這個階段的Column實例尚未創建,取而代之的是column_info參數到聽者根本屬性,您可以從您的原始柱覆蓋的字典:

{'primary_key': 0, 
'nullable': False, 
'default': None, 
'autoincrement': False, 
'type': VARCHAR(), 
'name': u'third_column'}