Python SQLAlchemy和numpy数据类型过滤

Python SQLAlchemy和numpy数据类型过滤,python,numpy,sqlalchemy,Python,Numpy,Sqlalchemy,SQLAlchemy.filter()函数似乎无法处理numpy数据类型。如果在filter参数中使用np.int32,则无法获得所需的结果。相反,我需要将np.int32转换为int,以使查询按预期工作 在下面的示例中,我从数据库查询值,通过numpy进行一些选择,然后使用减少的选择再次查询(我知道这不是一个有意义的操作,只是为了演示问题) 结果是 without cast: [] with cast: [(2.1,)] without cast: [] with cast: [(2.2,

SQLAlchemy.filter()函数似乎无法处理numpy数据类型。如果在filter参数中使用np.int32,则无法获得所需的结果。相反,我需要将np.int32转换为int,以使查询按预期工作

在下面的示例中,我从数据库查询值,通过numpy进行一些选择,然后使用减少的选择再次查询(我知道这不是一个有意义的操作,只是为了演示问题)

结果是

without cast: []
with cast: [(2.1,)] 
without cast: [] 
with cast: [(2.2,)]
我不确定,为什么numpy数据类型不起作用。我以前从未遇到过与numpy的任何兼容性问题。对我来说,这是一个相当严重的问题。当然,您可以强制转换,但由于没有警告或错误,因此很容易出现严重问题(意外丢失强制转换),因为如果您的查询不匹配,空列表当然是有效的响应

既然numpy和sqlalchemy都相当广泛,如果它们兼容的话那就太好了

我真的很奇怪,我在谷歌的任何地方都没有发现这个问题。所以也许我错过了什么或者做错了什么。感谢您的帮助

编辑: 问题在于SQLITE3API,而不是sqlalchemy。但是,在sqlalchemy的帮助下,我们可以使用TypeDecorators来解决这个问题:

编辑:
下面是一个stackoverflow,它介绍了如何在不使用sqlalchemy的情况下处理这个问题。我花了几个小时从不同的角度(
where()
子句)讨论了相同的基本问题。虽然上面的问题最终被编辑为提到了
TypeDecorator
类作为解决方案,但我想在这里实现该解决方案(使用sqlalchemy的核心API而不是ORM)。希望页面上扩展的措辞能够改善此问题的搜索结果

类似的MWE:
从pathlib导入路径
作为pd进口熊猫
从sqlalchemy导入(
创建引擎,
元数据,
桌子
专栏,
整数,
一串
选择,
插入,
)
eng=create_引擎(“sqlite://”+str(Path().resolve()/“temp.db”))
md=元数据()
tbl=表格(“用户”,md,列(“id”,整数),列(“名称”,字符串))
md.create_all(英语)
工程执行(插入(待定,(1,“千斤顶”))
stmt1=选择(tbl)。其中(tbl.c.id==1)
打印(eng.execute(stmt1.fetchall())
按预期返回:

[(1,'Jack')]
然而:

target_id=pd.read_sql(stmt1,eng).loc[:,'id'].max()
stmt2=选择(tbl)。其中(tbl.c.id==目标\U id)
打印(eng.execute(stmt2.fetchall())
返回:

[]
由于
pandas.read\u sql
将数据存储为numpy类型,因此选择无法按预期进行

TypeDecorator
解决方案 我们可以用

导入sqlalchemy.types作为类型
类整型(types.TypeDecorator):
impl=types.Integer
cache_ok=True
def process_bind_参数(自身、值、方言):
返回int(值)
如果我们删除上面刚刚创建的
temp.db
,并使用以下代码运行代码:

tbl = Table("users", md, Column("id", IntegerLike), Column("name", String))
诊断步骤? 我们可以从中看出一点问题所在

打印(stmt1)
选择users.id、users.name
来自用户
其中users.id=:id_1

:id_1
是一个绑定参数,由底层DBAPI处理。(我不知道如何实际强制DBAPI完整地呈现语句,因此我欢迎任何提供方法的评论或编辑)

我花了几个小时从不同的角度(
where()
子句)讨论了相同的基本问题。虽然上面的问题最终被编辑为提到了
TypeDecorator
类作为解决方案,但我想在这里实现该解决方案(使用sqlalchemy的核心API而不是ORM)。希望页面上扩展的措辞能够改善此问题的搜索结果

类似的MWE:
从pathlib导入路径
作为pd进口熊猫
从sqlalchemy导入(
创建引擎,
元数据,
桌子
专栏,
整数,
一串
选择,
插入,
)
eng=create_引擎(“sqlite://”+str(Path().resolve()/“temp.db”))
md=元数据()
tbl=表格(“用户”,md,列(“id”,整数),列(“名称”,字符串))
md.create_all(英语)
工程执行(插入(待定,(1,“千斤顶”))
stmt1=选择(tbl)。其中(tbl.c.id==1)
打印(eng.execute(stmt1.fetchall())
按预期返回:

[(1,'Jack')]
然而:

target_id=pd.read_sql(stmt1,eng).loc[:,'id'].max()
stmt2=选择(tbl)。其中(tbl.c.id==目标\U id)
打印(eng.execute(stmt2.fetchall())
返回:

[]
由于
pandas.read\u sql
将数据存储为numpy类型,因此选择无法按预期进行

TypeDecorator
解决方案 我们可以用

导入sqlalchemy.types作为类型
类整型(types.TypeDecorator):
impl=types.Integer
cache_ok=True
def process_bind_参数(自身、值、方言):
返回int(值)
如果我们删除上面刚刚创建的
temp.db
,并使用以下代码运行代码:

tbl = Table("users", md, Column("id", IntegerLike), Column("name", String))
诊断步骤? 我们可以从中看出一点问题所在

打印(stmt1)
选择users.id、users.name
来自用户
其中users.id=:id_1

:id_1
是一个绑定参数,由底层DBAPI处理。(我不知道如何实际强制DBAPI完整地呈现语句,因此我欢迎任何提供方法的评论或编辑)

在github中打开了一个问题。还有一个类似的问题,提到numpy时已经被拒绝了。整数不是标准的python整数。然而,我的观点是,鉴于numpy的广泛应用,至少应该实施一个警告:我在sqlite3测试中犯了一个错误。事实上,sqlite3并没有像预期的那样处理numpy.integer。sqlalchemy只是将值转发给DBAPI。所以炼金术不是错的