Python将Cassandra数据读取到pandas中

Python将Cassandra数据读取到pandas中,python,pandas,cassandra,Python,Pandas,Cassandra,将卡桑德拉数据读入熊猫的正确且最快的方法是什么?现在我使用下面的代码,但速度非常慢 import pandas as pd from cassandra.cluster import Cluster from cassandra.auth import PlainTextAuthProvider from cassandra.query import dict_factory auth_provider = PlainTextAuthProvider(username=CASSANDRA_U

将卡桑德拉数据读入熊猫的正确且最快的方法是什么?现在我使用下面的代码,但速度非常慢

import pandas as pd

from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
from cassandra.query import dict_factory

auth_provider = PlainTextAuthProvider(username=CASSANDRA_USER, password=CASSANDRA_PASS)
cluster = Cluster(contact_points=[CASSANDRA_HOST], port=CASSANDRA_PORT,
    auth_provider=auth_provider)

session = cluster.connect(CASSANDRA_DB)
session.row_factory = dict_factory

sql_query = "SELECT * FROM {}.{};".format(CASSANDRA_DB, CASSANDRA_TABLE)

df = pd.DataFrame()

for row in session.execute(sql_query):
    df = df.append(pd.DataFrame(row, index=[0]))

df = df.reset_index(drop=True).fillna(pd.np.nan)
阅读1000行需要1分钟,我有一个“多一点”。。。 如果我在DBeaver中运行相同的查询,我会在一分钟内得到整个结果(约40k行)


谢谢你

我在官方网站上得到了答案(效果非常好):

尝试定义您自己的工厂:

def pandas_factory(colnames, rows):
    return pd.DataFrame(rows, columns=colnames)

session.row_factory = pandas_factory
session.default_fetch_size = None

query = "SELECT ..."
rslt = session.execute(query, timeout=None)
df = rslt._current_rows
这就是我做这件事的方式-它应该更快

如果你找到一种更快的方法,我感兴趣:)

迈克尔

我(在python 3中)所做的是:


我一直致力于将数据从Cassandra移动到mssql,并使用这里给出的答案作为参考,我能够移动数据,但我在Cassandra中的源表很大,我的查询从Cassandra得到超时错误,问题是我们不能增加超时,我只剩下在查询中批量选择行的选项,我的代码还将cassandra collection数据类型转换为str,因为我想在mssql中插入这些数据类型,然后对其进行解析。如果有人面临类似问题,请告诉我,我构建的代码如下所示:

import sys
import pandas as pd
import petl as etl
import pyodbc
import sqlalchemy
from cassandra.auth import PlainTextAuthProvider
from cassandra.cluster import Cluster
from sqlalchemy import *
from cassandra.query import SimpleStatement


def pandas_factory(colnames, rows):
    return pd.DataFrame(rows, columns=colnames)
    engine = sqlalchemy.create_engine('sql_server_connection string')

cluster = Cluster(
    contact_points=['cassandra_host'], 
    auth_provider = PlainTextAuthProvider(username='username', password='passwrd')
)

session = cluster.connect('keyspace',wait_for_all_pools=True)

session.row_factory = pandas_factory
request_timeout = 60000
query = "SELECT * FROM cassandratable"
statement = SimpleStatement(query, fetch_size=5000) 
rows = session.execute(statement)

df = rows._current_rows
df['attributes'] = df.attributes.astype(str)
df['attributesgenerated'] = df.attributesgenerated.astype(str)
df['components'] = df.components.astype(str)
df['distributioncenterinfo'] = df.distributioncenterinfo.astype(str)
df['images'] = df.images.astype(str)
df['itemcustomerzonezoneproductids'] = 
df.itemcustomerzonezoneproductids.astype(str)
df['itempodconfigids'] = df.itempodconfigids.astype(str)
df['keywords'] = df.keywords.astype(str)
df['validationmessages'] = df.validationmessages.astype(str)
df['zones'] = df.zones.astype(str)
#error_bad_lines=False
#print(df)
df.to_sql(
           name='mssql_table_name',
           con=engine,
           index=False,
           if_exists='append',
           chunksize=1
         )

通过自动迭代页面将卡桑德拉数据读入熊猫的最快方式。创建字典并通过自动迭代所有页面将每个字典添加到字典中。然后,使用此字典创建dataframe

import pandas as pd
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
from cassandra.query import dict_factory

auth_provider = PlainTextAuthProvider(username=CASSANDRA_USER, password=CASSANDRA_PASS)
cluster = Cluster(contact_points=[CASSANDRA_HOST], port=CASSANDRA_PORT,
    auth_provider=auth_provider)

session = cluster.connect(CASSANDRA_DB)
session.row_factory = dict_factory

sql_query = "SELECT * FROM {}.{};".format(CASSANDRA_DB, CASSANDRA_TABLE)

dictionary ={"column1":[],"column2":[]}

for row in session.execute(sql_query):
    dictionary["column1"].append(row.column1)
    dictionary["column1"].append(row.column1)

df = pd.DataFrame(dictionary)

我使用row_工厂解决方案几个星期,然后在尝试将数据帧写入另一个具有相同结构的表时遇到数据类型问题。Pandas为具有许多空字段的int列猜测了
float
数据类型。在写入过程中,cassandra驱动程序抱怨类型不匹配

TypeError: Received an argument of invalid type for column "frequency". Expected: <class 'cassandra.cqltypes.Int32Type'>, Got: <class 'float'>; (required argument is not an integer)
我还发现,如果我不想要行工厂,我可以这样做:
df=pandas.DataFrame(result.all())


作为一个临时解决方案,我希望有一个健壮的
result\u to_df()
函数,它使用
result.column\u类型
(例如:
cassandra.cqltypes.Int32Type
),并对如何将这些类型转换为python对象或numpy类型做出正确的猜测。如果我有时间写的话,我会编辑这个答案。Pandas
read_cql
to_cql
将是理想的选择,但可能超出了我的带宽。

如果
session.execute(sql_query)
的输出是一个dict列表,我会尝试在这个列表的某个部分运行
pd.DataFrame
。将行逐个附加到数据帧是低效的。
session.execute(sql\u query)
的结果是一个特殊的
iterable对象。它的行可以是元组、命名元组或字典。不过,最好先将其转换为列表,例如
lst=[];对于会话中的行…:lst.append(row)
,如果其他方法无效。然后连接结果:
df=pd.concat(lst)
。通过这种方式,您可以避免对
pd.DataFrame.append
进行代价高昂的40k调用。这应该被标记为答案,它整洁、简洁且通用。即使是陌生人cassandra typesWorks也能很好地阅读,但在写回数据时可能会遇到问题,因为熊猫必须猜测数据类型。例如:我读取了一个包含许多空行的int列,我猜是float,然后CQL在插入类似表时给出了一个错误,因为该列的类型错误。
TypeError: Received an argument of invalid type for column "frequency". Expected: <class 'cassandra.cqltypes.Int32Type'>, Got: <class 'float'>; (required argument is not an integer)
def pandas_factory(colnames, rows):
    df = pd.DataFrame(rows, columns=colnames, dtype=object)
    return df