Why I get this message:
mismatched input 'UNIQUE' expecting ')' (...KEY (user_id),CONSTRAINT email_uq [UNIQUE]...)
I want to create this table:
CREATE TABLE users_by_id (user_id uuid, email text, password text, username text, user_info frozen<user_information>, user_since timestamp, PRIMARY KEY (user_id),CONSTRAINT email_uq UNIQUE (email));
CONSTRAINT is not supported by CQL and Cassandra. Applications have to take care of any constraint which you want to have. Below query will work fine
CREATE TABLE users_by_id (user_id uuid,\
email text,\
password text,\
username text,\
user_info frozen<user_information>,\
user_since timestamp,\
PRIMARY KEY (user_id));
Related
I am trying the following codes to create a keyspace and a table inside of it:
CREATE KEYSPACE IF NOT EXISTS books WITH REPLICATION = { 'class': 'SimpleStrategy',
'replication_factor': 3 };
CREATE TABLE IF NOT EXISTS books (
id UUID PRIMARY KEY,
user_id TEXT UNIQUE NOT NULL,
scale TEXT NOT NULL,
title TEXT NOT NULL,
description TEXT NOT NULL,
reward map<INT,TEXT> NOT NULL,
image_url TEXT NOT NULL,
video_url TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
But I do get:
SyntaxException: line 2:10 no viable alternative at input 'UNIQUE'
(...NOT EXISTS books ( id [UUID] UNIQUE...)
What is the problem and how can I fix it?
I see three syntax issues. They are mainly related to CQL != SQL.
The first, is that NOT NULL is not valid at column definition time. Cassandra doesn't enforce constraints like that at all, so for this case, just get rid of all of them.
Next, Cassandra CQL does not allow default values, so this won't work:
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
Providing the current timestamp for created_at is something that will need to be done at write-time. Fortunately, CQL has a few of built-in functions to make this easier:
INSERT INTO books (id, user_id, created_at)
VALUES (uuid(), 'userOne', toTimestamp(now()));
In this case, I've invoked the uuid() function to generate a Type-4 UUID. I've also invoked now() for the current time. However now() returns a TimeUUID (Type-1 UUID) so I've nested it inside of the toTimestamp function to convert it to a TIMESTAMP.
Finally, UNIQUE is not valid.
user_id TEXT UNIQUE NOT NULL,
It looks like you're trying to make sure that duplicate user_ids are not stored with each id. You can help to ensure uniqueness of the data in each partition by adding user_id to the end of the primary key definition as a clustering key:
CREATE TABLE IF NOT EXISTS books (
id UUID,
user_id TEXT,
...
PRIMARY KEY (id, user_id));
This PK definition will ensure that data for books will be partitioned by id, containing multiple user_id rows.
Not sure what the relationship is between books and users is, though. If one book can have many users, then this will work. If one user can have many books, then you'll want to switch the order of the keys to this:
PRIMARY KEY (user_id, id));
In summary, a working table definition for this problem looks like this:
CREATE TABLE IF NOT EXISTS books (
id UUID,
user_id TEXT,
scale TEXT,
title TEXT,
description TEXT,
reward map<INT,TEXT>,
image_url TEXT,
video_url TEXT,
created_at TIMESTAMP,
PRIMARY KEY (id, user_id));
I am currently executing a code, trying to create tables:
cur.executescript('''
CREATE TABLE User(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE ,
name TEXT, email_id TEXT);
CREATE TABLE Courses(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
course_name TEXT);
CREATE TABLE Member(
user_id INTEGER, course_id INTEGER, role INTEGER)/*student-0 teacher 1*/
PRIMARY KEY(user_id, course_id);
''')
It gives me this error:
File "E:\python_folder_practice_app_programming\SQLite\beginner_pro_db\beginner_pro_db.py", line 18, in
cur.executescript('''
sqlite3.OperationalError: near "PRIMARY": syntax error
Can someone help me debug this?
This is the problematic statement
CREATE TABLE Member(
user_id INTEGER, course_id INTEGER, role INTEGER)/*student-0 teacher 1*/
PRIMARY KEY(user_id, course_id);
Your primary key constraint should be inside the parens (and separated by comma)
Like this (I've broken it into several lines for readability)
CREATE TABLE Member(
user_id INTEGER,
course_id INTEGER,
role INTEGER, /*student-0 teacher 1*/
PRIMARY KEY(user_id, course_id)
);
See examples here https://www.sqlitetutorial.net/sqlite-create-table/
tried to create the following table:
CREATE TABLE customTableSchema(
id UUID PRIMARY KEY,
table_id UUID,
schema text,
created_at timestamp,
last_modified_at timestamp,
);
came up with this error:
SyntaxException: line 4:8 missing ')' at '<missing '
The schema is reserved keyword in the Cassandra Query Language, so you can't use it (see this table in the docs).
Since "schema" is a reserverd keyword, you cannot use your query in current form. If you intend to use it then you can do it as below
CREATE TABLE customTableSchema(
id UUID PRIMARY KEY,
table_id UUID,
"schema" text,
created_at timestamp,
last_modified_at timestamp,
);
You can refer this page for reserved cql keywords.
I have the following table.
CREATE TABLE codingjedi.users (
bucket int,
email text,
authprovider text,
firstname text,
lastname text,
confirmed boolean,
hasher text,
id uuid,
password text,
salt text,
PRIMARY KEY ((bucket, email), authprovider, firstname, lastname)
) WITH CLUSTERING ORDER BY (authprovider ASC, firstname ASC, lastname ASC)
I tried to update a row of the table but I didn't fully qualify the row. I specified only partition key and partially specified the clustering columns
def updateValues(tableName:String, model:User, id:UserKeys):Update.Where = {
QueryBuilder.update(tableName).`with`(QueryBuilder.set("confirmed",model.profile.internalProfileDetails.get.confirmed))/*(QueryBuilder.set("authprovider",model.profile.internalProfileDetails.get.loginInfo.providerID)) //TODOM - remove hardcoding for bucket and also add bucket in User model*/
.and(QueryBuilder.set("id",model.id))
.and(QueryBuilder.set("password",model.profile.internalProfileDetails.get.passwordInfo.get.password))
.and(QueryBuilder.set("hasher",model.profile.internalProfileDetails.get.passwordInfo.get.hasher))
.and(QueryBuilder.set("salt",""/*model.profile.internalProfileDetails.get.passwordInfo.get.salt.get*/)) //salt is empty for BCryptSha256PasswordHasher. The 'hash' method of BCryptSha256PasswordHasher does not return the salt separately because it is embedded in the hashed password.
.where(QueryBuilder.eq("bucket", id.bucket)) //TODOM - pick column names from config/env file
.and(QueryBuilder.eq("email", id.email))
.and(QueryBuilder.eq("authprovider", model.profile.internalProfileDetails.get.loginInfo.providerID))//TODOM - this should come from id
.and(QueryBuilder.eq("firstname",model.profile.externalProfileDetails.firstName))
/*.and(QueryBuilder.eq("lastname",model.profile.externalProfileDetails.lastName))*//*REMOVED a clustering column value*/
}
The above query fails and the row isn't updated but I also don't see any error messages in the console.
But if I try the same in cqlsh, I see error InvalidRequest: Error from server: code=2200 [Invalid query] message="Some clustering keys are missing: lastname".
Why Datastax isn't reporting error and how could I make it show errors?
I have a case class which represents partition key values.
case class UserKeys (bucket:Int,
email: String)
I create query Clauses as follows:
def conditions(id: UserKeys):List[Clauses] = List(
QueryBuilder.eq("bucket", id.bucket), //TODOM - pick table description from config/env file.
QueryBuilder.eq("email", id.email)
)
And use the query as follows
val selectStmt =
select()
.from(tablename)
.where(QueryBuilder.eq(partitionKeyColumns(0), whereClauseList(0))).and(QueryBuilder.eq(partitionKeyColumns(1), whereClauseList(1)))
.limit(1)
I am getting following error.
com.datastax.driver.core.exceptions.InvalidTypeException: Value 0 of type class com.datastax.driver.core.querybuilder.Clause$SimpleClause does not correspond to any CQL3 type
Question 1 - What am I doing wrong?
The query works on cqlsh
The table I am querying is
CREATE TABLE users (
bucket int,
email text,
firstname text,
lastname text,
authprovider text,
password text,
PRIMARY KEY ((bucket, email), firstname, lastname)
Question 2 - Is there a way to print the List which contains the query clauses? I tried it but I get this incomprehensible text.
List(com.datastax.driver.core.querybuilder.Clause$SimpleClause#2389b3ee, com.datastax.driver.core.querybuilder.Clause$SimpleClause#927f81)
My bad, I was using the query clauses incorrectly. Rather than
.where(QueryBuilder.eq(partitionKeyColumns(0), whereClauseList(0))).and(QueryBuilder.eq(partitionKeyColumns(1), whereClauseList(1)))
I needed to do
.where(whereClauseList(0)).and(whereClauseList(1))
because the List already has QueryBuilder.eq("bucket", id.bucket) part