Use a driver with Astra DB
This quickstart demonstrates how to configure a DataStax driver, and then use the driver to connect and interact with an Astra DB database.
The quickstart demo application inserts a row of user data, selects the new row, updates the row, and then deletes the row. If you prefer to run the full script directly, see Complete code example.
To get the most of out your experience with the drivers, refer to Best practices for DataStax drivers.
Prerequisites
You need the following:
-
An active Astra DB Classic database.
-
The
clientId
andclientSecret
for an application token that can access your database. -
Your database’s Secure Connect Bundle (SCB).
-
The name of the keyspace in your database that you want to connect to. This quickstart uses a keyspace named
demo
.
Install a driver
DataStax provides drivers for multiple programming languages. There are common features across all the drivers with similar capabilities.
Make sure you specify the driver as a dependency of your project. Your project relies on the driver to communicate with Astra DB.
For Java, this means specifying the Java driver as a dependency of your project. For other platforms, this means downloading and installing the driver package using package management software for that platform.
-
Java
-
Python
-
Node.js
-
C#
Replace VERSION
with the current Java driver version .
<!--If using Maven, add the following dependencies to your pom.xml file-->
<!--Use the latest version from https://search.maven.org/artifact/com.datastax.oss/java-driver-core -->
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-core</artifactId>
<version>VERSION</version>
</dependency>
To use Gradle with the Java Driver, see Minimal Project Structure. |
# We highly recommend the use of a virtual env
pip install cassandra-driver
npm install cassandra-driver
dotnet add package CassandraCSharpDriver -v 3.17.0
Import dependencies
To begin your driver script, import the necessary classes or modules to use the driver API.
-
Java
-
Python
-
Node.js
-
C#
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.cql.*;
import java.nio.file.Paths;
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
const cassandra = require('cassandra-driver');
using Cassandra;
using System.Linq;
using System;
Connect to Astra DB
Create a cluster object and session object to connect to your running Astra DB instance. For more information, see Connecting to Astra DB: Driver Configuration.
-
Java
-
Python
-
Node.js
-
C#
// add to your main() method
try (CqlSession cqlSession = CqlSession.builder()
// make sure you change the path to the secure connect bundle below
.withCloudSecureConnectBundle(Paths.get("PATH_TO_SCB"))
.withAuthCredentials("clientId","clientSecret")
.withKeyspace("demo")
.build())
cloud_config= {
'secure_connect_bundle': 'PATH_TO_SCB'
}
auth_provider = PlainTextAuthProvider('clientId', 'clientSecret')
cluster = Cluster(cloud=cloud_config, auth_provider=auth_provider)
session = cluster.connect('demo')
const client = new cassandra.Client({
cloud: { secureConnectBundle: 'PATH_TO_SCB' },
credentials: { username: 'clientId', password: 'clientSecret' }
keyspace: 'demo'
});
Cluster.Builder()
.WithCloudSecureConnectionBundle(@"C:*PATH_TO_SCB*")
.WithCredentials("clientId", "clientSecret")
.Build();
ISession session = cluster.Connect("demo");
Create a table
A keyspace is a group of tables.
Add code to your script to create a users
table.
If you are familiar with SQL, the notation will be familiar to you:
sql CREATE TABLE demo.users ( lastname text PRIMARY KEY, age int, city text, email text, firstname text);
Execute a simple statement against the database that will create the users
table.
Be sure to change the name of the keyspace to the one you are using.
-
Java
-
Python
-
Node.js
-
C#
cqlSession.execute("CREATE TABLE IF NOT EXISTS demo.users ("
+ " lastname text PRIMARY KEY,"
+ " age int,"
+ " city text,"
+ " email text," +
" firstname text)");
session.execute(
"""
CREATE TABLE IF NOT EXISTS demo.users (
lastname text PRIMARY KEY,
age int,
city text,
email text,
firstname text);
"""
)
function createTable(){
const query = "CREATE TABLE IF NOT EXISTS demo.users \
(lastname text PRIMARY KEY, age int, city text, email text, firstname text);";
return client.execute(query);
}
var statement = new SimpleStatement("CREATE TABLE IF NOT EXISTS demo.users ("
+ " lastname text PRIMARY KEY,"
+ " age int,"
+ " city text,"
+ " email text," +
" firstname text)");
session.Execute(statement);
Add a row
Now add some simple CRUD operations to interact with your table. Create a method or function to insert one user into the table.
In this example, we use positional placeholders in our statement and add values separately. The values are assigned based on the position of placeholders. One advantage of placeholders is that they avoid injection attacks if the values are dynamic.
-
Java
-
Python
-
Node.js
-
C#
private static void setUser(CqlSession cqlSession, String lastname, int age,
String city, String email, String firstname) {
//Insert one user into the table
cqlSession.execute(
SimpleStatement.builder( "INSERT INTO users (lastname, age, city, email, firstname) "
+ "VALUES (?,?,?,?,?)")
.addPositionalValues(lastname, age, city, email, firstname)
.build());
}
def set_user(session, lastname, age, city, email, firstname):
# Insert one user into the table
session.execute("INSERT INTO users (lastname, age, city, email, firstname) VALUES (%s,%s,%s,%s,%s)", [lastname, age, city, email, firstname])
function insertUser(lastname, age, city, email, firstname) {
// Insert one user into the table
const insert = 'INSERT INTO users (lastname, age, city, email, firstname) VALUES (?,?,?,?,?)';
const params = [ lastname, age, city, email, firstname ];
return client.execute(insert, params);
}
private static void SetUser(ISession session, String lastname, int age, String city, String email, String firstname)
{
//Insert one user into the table
var statement = new SimpleStatement("INSERT INTO users (lastname, age, city, email, firstname) VALUES (?,?,?,?,?)", lastname, age, city, email, firstname);
session.Execute(statement);
}
Select a row
Select the user you inserted in the previous step.
This select query uses named placeholders, an alternative to the positional placeholders used in the insert statement. Using named placeholders has a few advantages over positional placeholders:
-
It is easier to read. If the values come from some other part of your code, it looks cleaner than doing the concatenation yourself.
-
You don’t need to translate the values to their string representation. The driver will send them alongside the query, in their serialized binary form.
Whether you use positional or named placeholders, the number of values must match the number of placeholders in the query string and their types must match the database schema.
-
Java
-
Python
-
Node.js
-
C#
private static void getUser(CqlSession session, String lastname) {
//Retrieve one user from the table
//Print firstname and age of user
ResultSet rs = session.execute(
SimpleStatement.builder("SELECT * FROM users WHERE lastname=:n")
.addPositionalValue(lastname)
.build());
Row row = rs.one();
System.out.format("%s %d\n", row.getString("firstname"), row.getInt("age"));
}
def get_user(session, lastname):
# Retrieve one user from the table
# Print firstname and age of user
result = session.execute("SELECT * FROM users WHERE lastname = %(lastname)s", [lastname]).one()
print result.firstname, result.age
function selectUser(lastname) {
// Retrieve one user from the table
const select = 'SELECT firstname, age FROM users WHERE lastname = :lastname';
const params = [ lastname ] ;
return client.execute(select, params);
}
private static void GetUser(ISession session, String lastname){
//Retrieve one user from the table
//Print firstname and age of user
var statement = new SimpleStatement("SELECT * FROM users WHERE lastname = :lastname", lastname);
var result = session.Execute(statement).First();
Console.WriteLine("{0} {1}", result["firstname"], result["age"]);
}
Update data in a row
Prepared statements are a good idea if you have to execute the same query more than once. You prepare the statement once, and then you can bind values and execute it multiple times.
Prepare statements have the following advantages:
-
They are faster than just using strings, especially if you are executing the same query over and over.
-
They are parsed once server-side and cached so they can be used again without resending the entire query each time it is executed.
-
They are used for repeated queries in production applications, so using them wherever a repeated query is used is a good habit to learn.
-
They are more secure because they prevent CQL injection attacks. By using prepared statements, you force the user input to be handled as the content of a parameter and not as a part of the statement itself.
-
Java
-
Python
-
Node.js
-
C#
private static void updateUser(CqlSession session, int age, String lastname) {
//Update the age of one user
PreparedStatement prepared = session.prepare(
"UPDATE users SET age =? WHERE lastname =?");
BoundStatement bound = prepared.bind(age, lastname);
session.execute(bound);
}
def update_user(session, new_age, lastname):
prepared = session.prepare("UPDATE users SET age = ? WHERE lastname = ?")
session.execute(prepared, [new_age, lastname])
function updateUser(age, lastname) {
// Update the age of one user
const update = 'UPDATE users SET age = ? WHERE lastname = ?';
return client.execute(update, [ age, lastname ], { prepare : true } )
}
private static void UpdateUser(ISession session, int age, String lastname) {
// Update the age of one user
PreparedStatement prepared = session.Prepare("UPDATE users SET age =? WHERE lastname = ?");
BoundStatement bound = prepared.Bind(age, lastname);
session.Execute(bound);
}
Delete a row
Like the previous step, you should consider the performance and security of your data and use a prepared statement for your query.
For more information on using prepared statements with each driver, see Best Practices for DataStax drivers.
-
Java
-
Python
-
Node.js
-
C#
private static void deleteUser(CqlSession session, String lastname) {
// Delete one user from the table
PreparedStatement prepared = session.prepare(
"DELETE FROM users WHERE lastname=?");
BoundStatement bound = prepared.bind(lastname);
session.execute(bound);
}
def delete_user(session, lastname):
prepared = session.prepare("DELETE FROM users WHERE lastname = ?")
session.execute(prepared, [lastname])
function deleteUser(lastname) {
// Delete one user from the table
const remove = 'DELETE FROM users WHERE lastname = ?';
const params = [ lastname ];
return client.execute(remove, params, { prepare: true })
}
private static void DeleteUser(ISession session, String lastname) {
PreparedStatement prepared = session.Prepare("DELETE FROM users WHERE lastname = ?");
BoundStatement bound = prepared.Bind(lastname);
session.Execute(bound);
}
Call the functions and run the program
Provide inputs for the script, and then run the quickstart application.
-
Java
-
Python
-
Node.js
-
C#
public static void main(String[] args) {
try (CqlSession session = CqlSession.builder()
// make sure you change the path to the secure connect bundle below
.withCloudSecureConnectBundle(Paths.get("PATH_TO_SCB"))
.withAuthCredentials("clientId","clientSecret")
.withKeyspace("demo")
.build()) {
session.execute("CREATE TABLE IF NOT EXISTS demo.users ("
+ " lastname text PRIMARY KEY,"
+ " age int,"
+ " city text,"
+ " email text,"
+ " firstname text)");
setUser(session, "Jones", 35, "Austin", "bob@example.com", "Bob");
getUser(session, "Jones");
updateUser(session, 36, "Jones");
getUser(session, "Jones");
deleteUser(session, "Jones");
}
}
def main():
cloud_config= {
'secure_connect_bundle': 'PATH_TO_SCB'
}
auth_provider = PlainTextAuthProvider('clientId', 'clientSecret')
cluster = Cluster(cloud=cloud_config, auth_provider=auth_provider)
session = cluster.connect('demo')
session.execute(
"""
CREATE TABLE IF NOT EXISTS demo.users (
lastname text PRIMARY KEY,
age int,
city text,
email text,
firstname text);
"""
)
lastname = "Jones"
age = 35
city = "Austin"
email = "bob@example.com"
firstname = "Bob"
new_age = 36
set_user(session, lastname, age, city, email, firstname)
get_user(session, lastname)
update_user(session, new_age, lastname)
get_user(session, lastname)
delete_user(session, lastname)
if name == "main":
main()
async function example() {
await client.connect();
await insertUser('Jones', 35, 'Austin', 'bob@example.com', 'Bob');
const rs1 = await selectUser('Jones');
const user1 = rs1.first();
if (user1) {
console.log("name = %s, age = %d", user1.firstname, user1.age);
} else {
console.log("No results");
}
await updateUser(36, 'Jones');
const rs2 = await selectUser('Jones');
const user2 = rs2.first();
if (user2) {
console.log("name = %s, age = %d", user2.firstname, user2.age);
} else {
console.log("No results");
}
await deleteUser('Jones');
await client.shutdown();
}
example();
static void Main(string[] args)
{
Cluster cluster = Cluster.Builder()
.WithCloudSecureConnectionBundle(@"C:*PATH_TO_SCB*")
.WithCredentials("clientId", "clientSecret")
.Build();
ISession session = cluster.Connect("demo");
var statement = new SimpleStatement("CREATE TABLE IF NOT EXISTS demo.users ("
+ " lastname text PRIMARY KEY,"
+ " age int,"
+ " city text,"
+ " email text," +
" firstname text)");
session.Execute(statement);
SetUser(session, "Jones", 35, "Austin", "bob@example.com", "Bob");
GetUser(session, "Jones");
UpdateUser(session, 36, "Jones");
GetUser(session, "Jones");
DeleteUser(session, "Jones");
cluster.Dispose();
}
Complete code example
-
Java
-
Python
-
Node.js
-
C#
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.cql.*;
import java.nio.file.Paths;
public class GettingStartedComplete {
public static void main(String[] args) {
try (CqlSession session = CqlSession.builder()
// make sure you change the path to the secure connect bundle below
.withCloudSecureConnectBundle(Paths.get("PATH_TO_SCB"))
.withAuthCredentials("clientId","clientSecret")
.withKeyspace("demo")
.build()) {
session.execute("CREATE TABLE IF NOT EXISTS demo.users ("
+ " lastname text PRIMARY KEY,"
+ " age int,"
+ " city text,"
+ " email text,"
+ " firstname text)");
setUser(session, "Jones", 35, "Austin", "bob@example.com", "Bob");
getUser(session, "Jones");
updateUser(session, 36, "Jones");
getUser(session, "Jones");
deleteUser(session, "Jones");
}
}
private static void setUser(CqlSession cqlSession, String lastname, int age, String city, String email, String firstname) {
// Insert one user into the table
cqlSession.execute(
SimpleStatement.builder( "INSERT INTO users (lastname, age, city, email, firstname) "
+ "VALUES (?,?,?,?,?)")
.addPositionalValues(lastname, age, city, email, firstname)
.build());
}
private static void getUser(CqlSession session, String lastname) {
// Retrieve one user from the table
// Print firstname and age of user
ResultSet rs = session.execute(
SimpleStatement.builder("SELECT * FROM users WHERE lastname=:n")
.addPositionalValue(lastname)
.build());
Row row = rs.one();
System.out.format("%s %d\n", row.getString("firstname"), row.getInt("age"));
}
private static void updateUser(CqlSession session, int age, String lastname) {
// Update the age of one user
PreparedStatement prepared = session.prepare(
"UPDATE users SET age =? WHERE lastname =?");
BoundStatement bound = prepared.bind(age, lastname);
session.execute(bound);
}
private static void deleteUser(CqlSession session, String lastname) {
// Delete one user from the table
PreparedStatement prepared = session.prepare(
"DELETE FROM users WHERE lastname=?");
BoundStatement bound = prepared.bind(lastname);
session.execute(bound);
}
}
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
def set_user(session, lastname, age, city, email, firstname):
# Insert one user into the table
session.execute("INSERT INTO users (lastname, age, city, email, firstname) VALUES (%s,%s,%s,%s,%s)", [lastname, age, city, email, firstname])
def get_user(session, lastname):
# Retrieve one user from the table
# Print firstname and age of user
result = session.execute("SELECT * FROM users WHERE lastname = %(surname)s", {'surname':lastname}).one()
print result.firstname, result.age
def update_user(session, new_age, lastname):
# Update the age of one user
prepared = session.prepare("UPDATE users SET age = ? WHERE lastname = ?")
session.execute(prepared, [new_age, lastname])
def delete_user(session, lastname):
# Delete one user
prepared = session.prepare("DELETE FROM users WHERE lastname = ?")
session.execute(prepared, [lastname])
def main():
cloud_config= {
'secure_connect_bundle': 'PATH_TO_SCB'
}
auth_provider = PlainTextAuthProvider('clientId', 'clientSecret')
cluster = Cluster(cloud=cloud_config, auth_provider=auth_provider)
session = cluster.connect('demo')
session.execute(
"""
CREATE TABLE IF NOT EXISTS demo.users (
lastname text PRIMARY KEY,
age int,
city text,
email text,
firstname text);
"""
)
lastname = "Jones"
age = 35
city = "Austin"
email = "bob@example.com"
firstname = "Bob"
new_age = 36
set_user(session, lastname, age, city, email, firstname)
get_user(session, lastname)
update_user(session, new_age, lastname)
get_user(session, lastname)
delete_user(session, lastname)
if name == "main":
main()
const cassandra = require('cassandra-driver');
const client = new cassandra.Client({
cloud: { secureConnectBundle: 'PATH_TO_SCB' },
credentials: { username: 'clientId', password: 'clientSecret' }
keyspace: 'demo'
});
function createTable(){
const query = "CREATE TABLE IF NOT EXISTS demo.users (lastname text PRIMARY KEY, age int, city text, email text, firstname text);";
return client.execute(query);
}
function insertUser(lastname, age, city, email, firstname) {
// Insert one user into the table
const insert = 'INSERT INTO users (lastname, age, city, email, firstname) VALUES (?,?,?,?,?)';
const params = [ lastname, age, city, email, firstname ];
return client.execute(insert, params, { prepare : true });
}
function selectUser(lastname) {
// Retrieve one user from the table
const select = 'SELECT firstname, age FROM users WHERE lastname = :lastname';
const params = [ lastname ] ;
return client.execute(select, params, { prepare : true });
}
function updateUser(age, lastname) {
// Update the age of one user
const update = 'UPDATE users SET age = ? WHERE lastname = ?';
return client.execute(update, [ age, lastname ], { prepare : true } )
}
function deleteUser(lastname) {
// Delete one user from the table
const remove = 'DELETE FROM users WHERE lastname = ?';
const params = [ lastname ];
return client.execute(remove, params, { prepare: true })
}
async function example() {
await client.connect();
await createTable();
await insertUser('Jones', 35, 'Austin', 'bob@example.com', 'Bob');
const rs1 = await selectUser('Jones');
const user1 = rs1.first();
if (user1) {
console.log("name = %s, age = %d", user1.firstname, user1.age);
} else {
console.log("No results");
}
await updateUser(36, 'Jones');
const rs2 = await selectUser('Jones');
const user2 = rs2.first();
if (user2) {
console.log("name = %s, age = %d", user2.firstname, user2.age);
} else {
console.log("No results");
}
await deleteUser('Jones');
await client.shutdown();
}
example();
using Cassandra;
using System.Linq;
using System;
namespace QuickStart
{
class AstraConnect
{
static void Main(string[] args)
{
Cluster cluster = Cluster.Builder()
.WithCloudSecureConnectionBundle(@"C:*PATH_TO_SCB*")
.WithCredentials("clientId", "clientSecret")
.Build();
ISession session = cluster.Connect("demo");
var statement = new SimpleStatement("CREATE TABLE IF NOT EXISTS demo.users ("
+ " lastname text PRIMARY KEY,"
+ " age int,"
+ " city text,"
+ " email text," +
" firstname text)");
session.Execute(statement);
SetUser(session, "Jones", 35, "Austin", "bob@example.com", "Bob");
GetUser(session, "Jones");
UpdateUser(session, 36, "Jones");
GetUser(session, "Jones");
DeleteUser(session, "Jones");
cluster.Dispose();
}
private static void SetUser(ISession session, String lastname, int age, String city, String email, String firstname)
{
//Insert one user into the table
var statement = new SimpleStatement("INSERT INTO users (lastname, age, city, email, firstname) VALUES (?,?,?,?,?)", lastname, age, city, email, firstname);
session.Execute(statement);
}
private static void GetUser(ISession session, String lastname)
{
// Retrieve one user from the table
// Print firstname and age of user
var statement = new SimpleStatement("SELECT * FROM users WHERE lastname = :lastname", lastname);
var result = session.Execute(statement).First();
Console.WriteLine("{0} {1}", result["firstname"], result["age"]);
}
private static void UpdateUser(ISession session, int age, String lastname)
{
// Update the age of one user
PreparedStatement prepared = session.Prepare("UPDATE users SET age =? WHERE lastname = ?");
BoundStatement bound = prepared.Bind(age, lastname);
session.Execute(bound);
}
private static void DeleteUser(ISession session, String lastname)
{
// Delete one user
PreparedStatement prepared = session.Prepare("DELETE FROM users WHERE lastname = ?");
BoundStatement bound = prepared.Bind(lastname);
session.Execute(bound);
}
}
}