SQLAlchemy列类型比较

8

我正在对不同类型的数据库进行大量的内省,希望能够比较两个列类型。例如,使用 declarative_base() 定义为 Boolean 类型的字段,然后转换为特定的 TINYINT 用于 MySQL 方言,因此可以进行以下检查:

model_a.__table__.columns['col'].type == model_b.__table__.columns['col'].type

这个不起作用,这个也不行:

(type_a == type_b) or issubclass(type_b, type_a)

如何比较两列的数据类型是否为“亲和性”?(通过检查代码,我看到列类型附有一个名为Comparator的类,但我不确定它是否有帮助以及如何使用它)。是否可以在SQLAlchemy配置中强制指定列类型(避免方言特定的转换)?
5个回答

5

因为我一直在研究这个问题,所以回答一个旧问题。

最快的解决方案是比较类型的str():

assert str(type_a) == (type_b)

这对于简单类型来说是可行的,但是如果您有任何Variant类型或包装器(例如,包装Postgres JSONMutableDict),则必须处理特殊情况。


类型转换为字符串可能无法表示类型特征,例如在SQLAlchemy 1.4.44中,“str(column.type)”将返回“NUMBER”,而“repr(column.type)”将返回“NUMBER(precision = 9,scale = 0,asdecimal = False)”。 - aturegano
转换为字符串可能无法表示类型特征,例如在SQLAlchemy 1.4.44中,str(column.type)将返回NUMBER,而repr(column.type)将返回NUMBER(precision=9, scale=0, asdecimal=False) - undefined

2
例如,要检查一个类型是否为BLOB,请使用以下代码:
import sqlalchemy as db
some code..
if type(column.type) is db.types.BLOB:
    something..

1

我建议比较列数据类型的repr()

repr(model_a.tables[table_name].columns[column_name].type) == \
repr(model_b.tables[table_name].columns[column_name].type)

请注意,将列类型转换为字符串可能无法表示详细的类型特征,例如在sqlalchemy 1.4.44中,str(column.type)会返回NUMBER,而repr(column.type)会返回NUMBER(precision=9, scale=0, asdecimal=False)

0

在2019年搜索相同答案时发现了这个线程 - 如果其他人也遇到同样的问题,以下是对我有效的解决方法。

要检查在表model_amodel_b中存在的列'col'的SQLAlchemy类型是否严格相等,请使用:

isinstance(model_a.columns['col'].type, type(model_b.columns['col'].type)) and
isinstance(model_b.columns['col'].type, type(model_a.columns['col'].type))

你需要同时使用isinstance语句(即" A是否是B?""B是否是A?")以拒绝任何情况下子类的列类型不完全相同。

不过,如果你的类型并不需要严格相等,而子类也可以接受,则可以删除其中一个isinstance语句。


这是一个不错的方法,但我感觉无法检测出两个类型分别为“NUMBER(9,0)”和“NUMBER(6,2)”的列之间的差异。 - aturegano
好的方法,但我想要能够检测到一个列的类型为NUMBER(9,0),而另一个列的类型为NUMBER(6,2)的区别。 - undefined

0

不确定这是否适用于您的特定用例,但您可以使用column.type.python_type基于它们各自的Python类型比较列类型。

ORM模型示例

class Example(Base)
    exCol1 = Column(String)
    exCol2 = Column(String)
    exCol3 = Column(Integer)

比较列类型:

In [1]: Example.__table__.columns['exCol1'].type.python_type == Example.__table__.columns['exCol2'].type.python_type
Out[1]: True
In [2]: Example.__table__.columns['exCol1'].type.python_type == Example.__table__.columns['exCol3'].type.python_type
Out[2]: False

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接