19

我想在 cassandra 中选择表的特定字段并将它们插入到另一个表中。我在 sql server 中这样做是这样的:

INSERT INTO Users(name,family)
SELECT name,family FROM Users

如何在 cassandra-cli 或 cqlsh 中做到这一点?

4

4 回答 4

28
COPY keyspace.columnfamily1 (column1, column2,...) TO 'temp.csv';
COPY keyspace.columnfamily2 (column1, column2,...) FROM 'temp.csv';

这里给出你的键空间(模式名称),而不是 columnfamilyname1 使用你想要复制到的表,并在 columnfamily2 中给出你想要复制的表名..

是的,这是 CQL 的解决方案,但是我从未尝试过使用 CLI。

于 2014-01-27T10:24:21.133 回答
5

对于不是很大的表,请自己保存文件并使用匿名管道:

cqlsh -e "COPY keyspace.src_table (col1, col2, ...,ColN ) TO STDOUT WITH HEADER=false" | cqlsh -e "COPY keyspace.target_table (col1, col2, ...,ColN ) FROM STDIN" 

对于非常大的数据集,这将不起作用。应探索每个令牌范围的策略

于 2017-02-05T16:05:23.850 回答
2

对于非常大的表,CQLSH 将很难处理 COPY TO/FROM。以下是如何按本地令牌范围扫描表并将所需列从一个表复制到另一个表。因为它使用本地副本,所以要在数据中心的每个节点上执行:

    #!/bin/bash
    #
    # Script to COPY from a SOURCE table's select columns over a TARGET table
    # Assumes the following:
    #
    # * The SOURCE table is very large - otherwise just try:
    #   cqlsh  -e "COPY keyspace.src_table (col1, col2, ...,ColN ) TO STDOUT WITH HEADER=false" \
    #   |cqlsh -e "COPY keyspace.tgt_table (col1, col2, ...,ColN ) FROM STDIN"
    # * SOURCE AND TARGET TABLES are in the SAME KEYSPACE
    # * TARGET columns are named the SAME as SOURCE
    #
    # The script sweeps thru the local tokens to copy only the local data over to the new table
    # Therefore, this script needs to run on every node on the datacenter
    #
    # Set these variables before executing
    #
    USR=cassandra
    PWD=password
    KSP=my_keyspace
    SRC=src_table
    COL="col1, col2, col3"
    PKY="col1"
    TGT=tgt_table

    CQLSH="cqlsh -u ${USR} -p ${PWD} -k ${KSP}"

    function getTokens(){
       for i in $($CQLSH -e "select tokens from system.local;" | awk -F, '/{/{print $0}' | tr -d '{' | tr -d '}' | tr -d ','); do
           echo ${i//\'/}
       done | sort -n
    }

    function getDataByTokenRange(){
       i=0
       tokens=($(getTokens))
       while [ ${i} -lt ${#tokens[@]} ]; do 
             [ ${i} -eq 0 ]         && echo "SELECT ${COL} FROM ${SRC} WHERE token(${PKY}) <= ${tokens[i]};" 
             [ "${tokens[i+1]}" ]   && echo "SELECT ${COL} FROM ${SRC} WHERE token(${PKY}) >  ${tokens[i]} AND token(${PKY}) <= ${tokens[i+1]};"
             [ ! "${tokens[i+1]}" ] && echo "SELECT ${COL} FROM ${SRC} WHERE token(${PKY}) >  ${tokens[i]};"
             ((i++))
       done
    } 

function cqlExec(){ 
  while IFS='' read -r cql || [[ -n "$line" ]]; do
    $CQLSH -e "CONSISTENCY LOCAL_ONE; $cql"                                                                \
    |awk -F\| '( !/LOCAL_ONE/ && !/'"${COL/, /|}"'/ && !/^\-+/ && !/^\([0-9]+ rows)/ && !/^$/ ){print $0}' \
    |sed -e 's/^[ ]*//g' -e 's/[ ]*|[ ]*/|/g'                                                              \
    |$CQLSH -e "COPY ${TGT} (${COL}) FROM STDIN WITH DELIMITER = '|' and HEADER=false;"
    [ "$?" -gt 0 ] && echo "ERROR: Failed to import data from command: ${command}"
  done < "$1"
}

    main(){
       echo "Begin processing ..."
       getDataByTokenRange > getDataByTokenRange.ddl
       cqlExec getDataByTokenRange.ddl
       echo "End procesing"
    }

    main
于 2017-02-05T22:10:55.413 回答
0

如果您(像我一样)拥有具有复杂类型或对象类型的数据,则使用 cqlsh COPY 复制数据会变得很棘手。我用 DataGrip 解决了我的问题。您可以将数据导出为插入语句,稍后您可以将 .cql 脚本直接加载到 cqlsh 中。

于 2022-01-07T19:36:30.113 回答