我在使用SQLAlchemy反映表时要使用的列定义字典,但是如果列实际存在于数据库中,我只想使用每个列定义。例如:
TABLE_DEFAULTS = {
'my_table': {
'my_column': Column(String),
'other_column': Column(String),
'third_column': Column(String, default='Sample')
}
}
让我们说我反映my_table
,它碰巧有third_column
和fourth_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中的某些内容只有在数据库中存在时才会覆盖列定义。
答案 0 :(得分:1)
假设每个应用程序只进行一次反射,我没有看到首先检查数据库以获取所需表的列的问题。实际上,您可以使用例程从原始TABLE_DEFAULTS
创建更新的字典,其余代码可以无需更改即可生效。
另一种方法是收听column_reflect
事件并根据需要修改列。但是在那个阶段,Column
实例还没有被创建,相反,该侦听器的column_info
参数只是一个属性字典,您可以从原始列覆盖:
{'primary_key': 0,
'nullable': False,
'default': None,
'autoincrement': False,
'type': VARCHAR(),
'name': u'third_column'}