这是我尝试过的:
dask_rf = dd.from_pandas(pd.read_sql('select ...)', conn_cx_Oracle), npartitions = 10)
这给了我一个“大对象”警告,建议使用client.scatter。问题在于,似乎client.scatter首先需要将数据加载到Pandas数据帧中,这就是为什么由于RAM限制我首先使用Dask的原因。
Oracle表太大,无法使用Dask的read_sql_table进行读取,因为read_sql_table不会以任何方式过滤该表。
想法? Dask不适用于我的用例吗?
编辑-以下每个答案以及研究方法之后,这是我尝试转换为使用sqlalchemy表达式的方法:
from sqlalchemy import create_engine, Table, Column, String, MetaData, select
sql_engine = create_engine(f'oracle+cx_oracle://username:password@environment')
metadata = MetaData(bind=sql_engine)
table_reference = Table('table', metadata, autoload=True, schema='schema')
s = select([table_reference ]).where(table_reference .c.field_to_filter == filtered_value)
import dask.dataframe as dd
dask_df = dd.read_sql_table(s, 'sqlalchemy_connection_string', 'index_col', schema = 'schema')
dask_df.count()
黄昏系列结构:npartitions = 1 action_timestamp int64 vendor_name ... dtype:int64 Dask名称:dataframe-count-agg, 1996年的任务
dask_df.count().compute()
DatabaseError:(cx_Oracle.DatabaseError)ORA-02391:已超出 同时限制SESSIONS_PER_USER(此错误的背景位于: http://sqlalche.me/e/4xp6)
为什么要连接到Oracle?
编辑#2-万一有帮助,我还进行了其他测试。我想证明sqlalchemy可以独立工作,所以我通过以下方式证明了这一点:
result = sql_engine.execute(s)
type(result)
sqlalchemy.engine.result.ResultProxy
result.fetchone()
显示了结果
这似乎排除了SQLAlchemy / Oracle问题,那么接下来有什么想法可以尝试?
答案 0 :(得分:1)
问题在于,似乎client.scatter需要先将数据加载到Pandas数据框中
那是因为您在这里调用Pandas代码
dd.from_pandas(pd.read_sql('select ...)', conn_cx_Oracle), npartitions = 10)
# pd.read_sql('select ...)', conn_cx_Oracle) # <<-----
根据read_sql_table
docstring
您应该能够传递SQLAlchemy表达式对象。
read_sql_table
不接受任意SQL查询字符串的原因是,它需要能够对查询进行分区,因此每个任务仅加载整个任务的一部分。对于许多其他方言,这是一件棘手的事情,因此我们依靠sqlalchemy进行格式化。
答案 1 :(得分:0)
我现在正在寻找相同的东西。
为了不被卡住...您可能没有足够的RAM,但可能有很多可用存储空间。所以...目前的建议
# imports
import pandas as pd
import cx_Oracle as cx
import dask.dataframe as dd
# Connection stuff
...
conn = ...
# Query
qry = "SELECT * FROM HUGE_TABLE"
# Pandas Chunks
for ix , chunk in enumerate(pd.io.sql.read_sql(qry , conn , ... , chunksize=1000000)):
pd.DataFrame(chunk).to_csv(f"chunk_{ix}.csv" , sep=";") # or to_parquet
# Dask dataframe reading from files (chunks)
dataset = dd.read_csv("chunk_*.csv" , sep=";" , blocksie=32e6) # or read_parquet
由于这是IO密集型操作,并且您要执行顺序操作,因此可能需要一段时间。
我建议更快地“导出”是对表进行分区,并按每个分区并行执行块导出。