Python 是否有方法将sqlalchemy查询中的数据附加到for循环中的pandas数据帧?

Python 是否有方法将sqlalchemy查询中的数据附加到for循环中的pandas数据帧?,python,pandas,sqlalchemy,Python,Pandas,Sqlalchemy,我目前正在for循环中从一个sqlalchemy查询中提取数据,该循环将不同的设备id/accon_时间对作为变量进行迭代 其思想是一次提取一个设备/时间对的数据,并将其附加到一个数据帧以供以后处理 其原因是批量甚至小批量提取数据会为我们的数据库触发高IOPS警报 起初,我尝试在循环中使用df.append(),但是我从查询对象中得到了一个类型错误 TypeError:无法连接“类”类型的对象 sqlalchemy.orm.query.query”;只有Series和DataFrame OBJ有

我目前正在for循环中从一个sqlalchemy查询中提取数据,该循环将不同的设备id/accon_时间对作为变量进行迭代

其思想是一次提取一个设备/时间对的数据,并将其附加到一个数据帧以供以后处理

其原因是批量甚至小批量提取数据会为我们的数据库触发高IOPS警报

起初,我尝试在循环中使用df.append(),但是我从查询对象中得到了一个类型错误

TypeError:无法连接“类”类型的对象 sqlalchemy.orm.query.query”;只有Series和DataFrame OBJ有效

然后,我决定尝试将查询对象转换为序列,然后将序列转换为数据帧:

for i in range(len(df)):
    dev_id = (df.iloc[i]['dev_id'])
    accon_time = (df.iloc[i]['accon_time'])
    new_session = Session()
    gps_qry = new_session.query(GPS).filter(GPS.dev_id == dev_id).filter(GPS.accon_time == accon_time). \
        filter(GPS.tm_time.between(20190620145813, 20190620151400))
    gps_qry = [repr(x) for x in gps_qry]
    ser_2 = pd.Series(data=gps_qry)
    #This part here is to split the comma seperated values in the series into 3 seperate columns:
    df_2 = ser_2.apply(lambda x: pd.Series([val.split('=')[1] for val in x[1:-1].split(',')]))
    df_2 = df_2.append(gps_qry, ignore_index=True)
    df_2.columns = ['dev_id', 'accon_time', 'tm_time']


print(df_2)
我期待着这样的事情:

     dev_id  accon_time  tm_time
0     'A'    'B'          'C'
1     'D'    'E'          'F'
2     'G'    'H'          'I'
但结果却是:

     dev_id       accon_time  tm_time
0     'A'           'B'          'C'
1     'D,E,F...'    NaN          NaN

我不太确定发生了什么,但这是我最接近解决这个问题的方法,因为其他方法都会引发类型错误,但是您可以使用
sqlalchemy
pandas
的组合,方法是访问使用ORM构建的原始查询,并按照@furas的建议将其传递给
read\u sql
。通过这种方式,您可以继续使用ORM创建查询

例如:

gps\u qry=new\u session.query(gps).filter(gps.dev\u id==dev\u id).filter(gps.accon\u time==accon\u时间)\
过滤器(GPS.tm_时间间隔(20190620145813、20190620151400))
gps\u df=pd.read\u sql(gps\u qry.statement,con=db.engine)
##或
gps\u df=pd.read\u sql(str(gps\u qry),con=db.engine)
或在循环中使用:

df_2=pd.DataFrame()
对于范围内的i(len(df)):
dev_id=(df.iloc[i]['dev_id'])
accon_time=int((df.iloc[i]['accon_time']))##更新为使用python int。
新建会话=会话()
gps\u qry=new\u session.query(gps).filter(gps.dev\u id==dev\u id).filter(gps.accon\u time==accon\u time)\
过滤器(GPS.tm_时间间隔(20190620145813、20190620151400))
###在每个循环中追加
gps\u df=pd.read\u sql(str(gps\u qry),con=db.engine)
df_2=pd.concat([df_2,gps_-df],轴=0,排序=False,忽略索引=True)
打印(df_2)

pandas
pd.read\u sql()
pd.read\u sql\u query()
直接从数据库读取。使用
print()
查看变量中的内容。它应该可以帮助您看到问题。为什么要使用
repr()
?转换某些东西是一种奇怪的方法。您可以尝试
gps\u qry=list(gps\u qry)
或直接
ser\u 2=pd.Series(data=list(gps\u qry))
,也许您将不需要
df.apply()
@furas我已经实际尝试过使用pd.read\u sql()和pd.read\u sql\u query(),但以前总是会收到这样的错误消息“nota executable object”@furas using repr()解决我之前遇到的一个错误,即我的数据表不可订阅。使用list()实际上会引发相同的错误对于循环的每次迭代,您仍然可以使用
.append
甚至
pd.concat
gps\u df
。使用.append或pd.concat都会引发此错误“不支持numpy.int64类型的Python值”您是否尝试将
开发id
转换为
int
?我更新了答案来考虑这个问题,因为一些数据库不会接受NUMPY/BANDAS整数类型。另外,会计时间的格式是什么?如果是整数,我也会使用相同的方法。accon_time是一个整数,但是dev_ID的ID值实际上是字符串,因为它们是字母和数字的组合。这就是问题所在。令人惊叹的!非常感谢您的修复和向我展示如何实际使用pd.read_sql()