【问题标题】:CassandraError: Undefined column name due to seeming case sensitivity despite consistent case in JavascritpCassandra 错误:尽管 Javascript 中大小写一致,但由于似乎区分大小写,未定义列名
【发布时间】:2018-04-01 07:07:32
【问题描述】:

我在一个 javascript 文件中执行了一条 Cassandra SQL 语句,其中包含多个参数,包括 networkInterfaces TEXT:

client.execute("CREATE TABLE IF NOT EXISTS testdb.networkData (latitude DOUBLE, longitude DOUBLE, allowsVoIP BOOLEAN, speed DOUBLE, uuid TEXT, timestamp TIMESTAMP PRIMARY KEY, networkType TEXT, carrierName TEXT, altitude DOUBLE, macAddress TEXT, publicIP TEXT, ssidLabel TEXT, networkInterfaces TEXT)", function (err, result) {
    if (!err){
        if ( result.rowLength > 0 ) {
            var data = result.rows[0];
            console.log("Total rows : "+ data.count);
        } else {
            console.log("No rows");
        }
    }else{
        console.log("count results err : "+err);
    }
});

在出现 networkInterfaces 的所有其他实例中使用相同的情况“networkInterfaces”。这包括向表中插入数据的代码:

// TODO: Save LAN interfaces as well
const recordCommand = 'INSERT INTO testdb.networkData (latitude, longitude, allowsVoIP, speed, uuid, timestamp, networkType, carrierName, altitude, macAddress, publicIP, ssidLabel, networkInterfaces) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
const params = [
    request.body.latitude,
    request.body.longitude,
    request.body.allowsVoIP,
    request.body.speed,
    request.body.uuid,
    request.body.timestamp,
    request.body.networkType,
    request.body.carrierName,
    request.body.altitude,
    request.body.macAddress,
    request.body.publicIP,
    request.body.ssidLabel,
    request.body.networkInterfaces
];

client.execute(recordCommand, params, { prepare: true }, function (error) {
    assert.ifError(error);
    //Inserted in the cluster
  });

然而,当命令被执行时,它说有一个未处理的错误如下:

错误:未定义的列名网络接口

未定义的列名似乎是大小写不匹配,但 networkInterfaces 的所有实例都具有相同的大小写。会不会有其他问题?

【问题讨论】:

    标签: javascript sql database cassandra


    【解决方案1】:

    默认情况下,Cassandra 会将所有表/列名称转换为小写。 如果需要区分大小写的表/列名,请将其括在双引号中。 使用desc table_name检查表详细信息。

    Eg:
    Create table test(Column1 text primary key,"Column2" text);
     will result in cassandra table with 2 columns (column1 [Note all are lower case] and Column2 [C is uppercase])
    

    【讨论】:

    • 我已将 CREATE TABLE 查询重新格式化如下:client.execute("CREATE TABLE IF NOT EXISTS testdb.chatmessagingtable (sender TEXT, content TEXT, timestamp DOUBLE PRIMARY KEY)", function (err, result) { ... }); 并插入如下:const recordCommand = 'INSERT INTO testdb.networkData (latitude, longitude, "allowsVoIP", speed, uuid, timestamp, "networkType", "carrierName", altitude, "macAddress", "publicIP", "ssidLabel", "networkInterfaces") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; 现在它会将引号视为键名的一部分
    • Error: Undefined column name "allowsVoIP" 是我在控制台中得到的
    • 我已将我的 INSERT 命令字符串重新格式化为 "INSERT INTO testdb.networkData (latitude, longitude, \"allowsVoIP\", speed, uuid, timestamp, \"networkType\", \"carrierName\", altitude, \"macAddress\", \"publicIP\", \"ssidLabel\", \"networkInterfaces\") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" 并且控制台仍然显示 Error: Undefined column name "allowsVoIP"。我想知道为什么它没有去掉引号。
    • 我添加了client.execute("DESC TABLE networkData;", function (err, result) {...});,控制台中的结果是no viable alternative at input 'DESC' ([DESC]...)
    【解决方案2】:

    这是更正脚本的示例。这里我的键空间名称是 yupoint。

    CREATE TABLE IF NOT EXISTS yupoint.user (
        id text,
        login text,
        password text,
        firstname text,
        lastname text,
        email text,
        activated boolean,
        lang_key text,
        activation_key text,
        reset_key text,
        reset_date timestamp,
        authorities set<text>,;
        PRIMARY KEY(id)
    );
    
    CREATE TABLE IF NOT EXISTS yupoint.user_by_login (
        login text,
        id text,
        PRIMARY KEY(login, id)
    );
    

    现在更改使用您的键空间并创建一些记录。

    使用yupoint;

    yupoint>INSERT INTO user (id, login, password , firstname, lastname ,email ,activated ,lang_key, activation_key, authorities)
    VALUES('3','admin','$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC','','Administrator','admin@localhost',true,'en','', {'ROLE_USER', 'ROLE_ADMIN'});
    
    yupoint>INSERT INTO user_by_login (login, id)
    VALUES('admin','3');
    

    【讨论】:

    • 我添加了一个 USE 命令,如下所示:client.execute("USE testdb", function (err, result) { ... }); 并且还编辑了 CREATE TABLE 语句:CREATE TABLE IF NOT EXISTS testdb.networkData (latitude DOUBLE, longitude DOUBLE, \"allowsVoIP\" BOOLEAN, speed DOUBLE, uuid TEXT, timestamp TIMESTAMP, \"networkType\" TEXT, \"carrierName\" TEXT, altitude DOUBLE, \"macAddress\" TEXT, \"publicIP\" TEXT, \"ssidLabel\" TEXT, \"networkInterfaces\" TEXT, PRIMARY KEY(timestamp)); 这并没有解决另一个答案的线程中描述的引号问题。
    • 尝试使用蛇形盒。示例:snake_case
    • 我已切换到snake_case:CREATE TABLE IF NOT EXISTS testdb.networkData (latitude DOUBLE, longitude DOUBLE, allows_voip BOOLEAN, speed DOUBLE, uuid TEXT, timestamp TIMESTAMP, network_type TEXT, carrier_name TEXT, altitude DOUBLE, mac_address TEXT, public_ip TEXT, ssid_label TEXT, network_interfaces TEXT, PRIMARY KEY(timestamp));INSERT INTO testdb.networkData (latitude, longitude, allows_voip, speed, uuid, timestamp, network_type, carrier_name, altitude, mac_address, public_ip, ssid_label, network_interfaces) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);。它找不到allows_voip
    • 即使将表名更改为snake_case networkDatanetwork_data 也是如此
    【解决方案3】:

    Cassandra 中的所有标识符(表名、列名等)不区分大小写,除非您将它们括在引号中每次引用它们时DataStax documentation on this

    因为这往往很乏味,所以大多数人使用snake_case 来命名表和列,例如network_datanetwork_type。如果你用引号括起来,这些标识符将继续出现在所有DESCRIBE 输出中的引号中:

    cqlsh:testdb> DESCRIBE TABLES;
    table1  table2  network_data  "networkData"  table5
    

    我已将您的查询调整为使用大写字母,并已在本地成功测试:

    const createTable = (
      `CREATE TABLE IF NOT EXISTS testdb."networkData" (
        latitude DOUBLE, 
        longitude DOUBLE, 
        "allowsVoIP" BOOLEAN, 
        speed DOUBLE, 
        uuid TEXT, 
        timestamp TIMESTAMP PRIMARY KEY, 
        "networkType" TEXT, 
        "carrierName" TEXT, 
        altitude DOUBLE, 
        "macAddress" TEXT, 
        "publicIP" TEXT, 
        "ssidLabel" TEXT, 
        "networkInterfaces" TEXT)`
    );
    
    const recordCommand = (
      `INSERT INTO testdb."networkData" (
        latitude, 
        longitude, 
        "allowsVoIP", 
        speed, 
        uuid, 
        timestamp, 
        "networkType",
        "carrierName", 
        altitude, 
        "macAddress", 
        "publicIP", 
        "ssidLabel", 
        "networkInterfaces"
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
    );
    
    const params = [
      request.body.latitude,
      request.body.longitude,
      request.body.allowsVoIP,
      request.body.speed,
      request.body.uuid,
      request.body.timestamp,
      request.body.networkType,
      request.body.carrierName,
      request.body.altitude,
      request.body.macAddress,
      request.body.publicIP,
      request.body.ssidLabel,
      request.body.networkInterfaces,
    ];
    
    const selectData = `SELECT * FROM testdb."networkData"`;
    
    client.connect()
      .then(() => client.execute(createTable))
      .then(() => client.execute(recordCommand, params, { prepare: true }))
      .then(() => client.execute(selectData))
      .then(result => {
        let count = result.rows.length
        if (count > 0)
          console.log(`Total rows : ${count}`)
        else console.log("No rows")
      })
      .catch(error => console.log(error));
    

    【讨论】:

      猜你喜欢
      • 2015-06-29
      • 2011-08-27
      • 2016-11-26
      • 1970-01-01
      • 1970-01-01
      • 2012-02-03
      • 2015-11-10
      • 2013-02-03
      • 1970-01-01
      相关资源
      最近更新 更多