Python将Cassandra数据读入pandas

时间:2016-12-20 16:48:51

标签: python pandas cassandra

将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_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行)。

谢谢!!!

5 个答案:

答案 0 :(得分:28)

我在官方mailing list得到了答案(它完美无缺):

  

您好,

     

尝试定义自己的pandas row factory:

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
     

这就是我这样做的方式 - 它应该更快......

     

如果您找到更快的方法 - 我对以下内容感兴趣:)

     

迈克尔

答案 1 :(得分:6)

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

[^>]*$

答案 2 :(得分:0)

我一直在努力将数据从Cassandra迁移到mssql,并使用此处给出的答案作为参考,我能够移动数据,但是我在cassandra中的源表很大,而且我的查询从cassandra中获取超时错误,是我们不能增加超时时间,而我只能选择在查询中成批选择行,我的代码还将cassandra集合数据类型转换为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
         )

答案 3 :(得分:0)

通过页面自动迭代将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_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)

答案 4 :(得分:0)

我使用row_factory解决方案了几个星期,然后在尝试将数据帧写入具有相同结构的另一个表时遇到了数据类型问题。 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)

Pandas int列不支持NaN或None,因此最好的选择可能是使该列成为python对象。

一个快速的技巧是调整pandas_factory以避免熊猫推断。不是理想的一揽子政策:

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

我还发现我可以做:df = pandas.DataFrame(result.all()),如果我不希望行工厂。

作为一个临时解决方案,我希望有一个健壮的result_to_df()函数,该函数使用result.column_types(例如:cassandra.cqltypes.Int32Type),并能很好地将其转换为python对象或numpy类型。如果/我有时间写答案时,将编辑此答案。熊猫read_cqlto_cql是理想的选择,但可能超出了我的带宽。