利用 Pandas DataFrame 作为 MySQL 查询中的参数

有一个名为 df 的 Pandas DataFrame,包含多列数据。
* 有一个名为 Table-B 的大型 MySQL 表,需要对 dfTable-B 进行左连接。
* 不希望将整个 Table-B 加载至 Pandas 中,因为这会占用大量内存且效率低下。
* 希望能够将 df 作为对象或参数传递给 read_sql 函数,以便在 MySQL 中直接进行查询。

  • 示例数据:
df = pd.DataFrame({'SEC1':['IBM','CSCO','MSFT','AMZN' ], 'SEC2':['GOOG', 'INTC', 'ABX', 'CREE'], 'HOUR':[10 ,10 ,15, 12], 'Size':[100 ,200 ,50 ,500],'Price':[300 ,25 ,150, 80] })

df = df[['SEC1', 'SEC2', 'HOUR', 'Size', 'Price']]

2、解决方案

  • 方式一:使用 df.to_sql() 函数将 df 临时存储到 MySQL 中

    • 可以使用 df.to_sql() 函数将 df 临时存储到 MySQL 中,然后在 MySQL 中执行查询,最后再使用 read_sql() 函数读取查询结果。
    • 在此方案中,需要确保具有相应的 MySQL 访问权限,并确保在执行查询之前已将 df 加载至 MySQL 中。
import pandas as pd
import sqlalchemy as SA
import config

df = pd.DataFrame({'SEC1':['IBM','CSCO','MSFT','AMZN' ], 'SEC2':['GOOG', 'INTC', 'ABX', 'CREE'], 'HOUR':[10 ,10 ,15, 12], 'Size':[100 ,200 ,50 ,500],'Price':[300 ,25 ,150, 80] })
df = df[['SEC1', 'SEC2', 'HOUR', 'Size', 'Price']]

engine = SA.create_engine('mysql+oursql://{u}:{p}@{h}/{d}'.format(
    u=config.USER, p=config.PASS, h=config.HOST, d='test'))
tablename = 'Table-A'
df.to_sql(tablename, engine, if_exists='replace')

sql = '''select * from  Table-A a
         left join Table-B b
         on (a.sec1 = b.sec1)
         where DATE_SUB(CURDATE(),INTERVAL 12 MONTH) <= dt
         group by 1,2,3,4,5,6,7'''

result = pd.read_sql(sql, engine)
  • 方式二:使用 read_sql_query() 函数将查询语句参数化

    • 可以使用 read_sql_query() 函数将查询语句参数化,然后在函数中直接传递 df 作为参数。
    • 在此方案中,需要确保具有相应的 MySQL 访问权限,并确保在执行查询之前已将 Table-B 加载至 MySQL 中。
import pandas as pd
import sqlalchemy as SA
import config

df = pd.DataFrame({'SEC1':['IBM','CSCO','MSFT','AMZN' ], 'SEC2':['GOOG', 'INTC', 'ABX', 'CREE'], 'HOUR':[10 ,10 ,15, 12], 'Size':[100 ,200 ,50 ,500],'Price':[300 ,25 ,150, 80] })
df = df[['SEC1', 'SEC2', 'HOUR', 'Size', 'Price']]

engine = SA.create_engine('mysql+oursql://{u}:{p}@{h}/{d}'.format(
    u=config.USER, p=config.PASS, h=config.HOST, d='test'))

sql = '''select * from  Table-A a
         left join Table-B b
         on (a.sec1 = b.sec1)
         where DATE_SUB(CURDATE(),INTERVAL 12 MONTH) <= dt
         group by 1,2,3,4,5,6,7'''

result = pd.read_sql_query(sql, engine, params={'df': df})
  • 方式三:使用 Pandas 的 merge()join() 函数进行连接

    • 可以使用 Pandas 的 merge()join() 函数将 dfTable-B 进行连接,无需将两者都加载至内存中。
    • 在此方案中,需要确保具有相应的 MySQL 访问权限,并确保在执行查询之前已将 Table-B 加载至 MySQL 中。
import pandas as pd
import sqlalchemy as SA
import config

df = pd.DataFrame({'SEC1':['IBM','CSCO','MSFT','AMZN' ], 'SEC2':['GOOG', 'INTC', 'ABX', 'CREE'], 'HOUR':[10 ,10 ,15, 12], 'Size':[100 ,200 ,50 ,500],'Price':[300 ,25 ,150, 80] })
df = df[['SEC1', 'SEC2', 'HOUR', 'Size', 'Price']]

engine = SA.create_engine('mysql+oursql://{u}:{p}@{h}/{d}'.format(
    u=config.USER, p=config.PASS, h=config.HOST, d='test'))

table_b = pd.read_sql_table('Table-B', engine)

result = pd.merge(df, table_b, on='SEC1', how='left')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值