Cassandra#

  • A production grade NoSQL database.

  • Can be distributed across servers, nodes, etc.

  • Replication of database is supported for high degree of redundancy and speed.

  • Uses CQL, a subset of SQL for querying.

  • Works seamlesly together with Spark and its corresponding distributed structure.

  • Installation of Cassandra is explained in the Installation chapter.

Spinning up a local Cassandra instance#

In a terminal, first time:
docker run --name my_cassandra -p 9042:9042 cassandra:latest
… and later:
docker start my_cassandra

… or in Docker Desktop:

  • Run the cassandra docker image with optional settings, opening 9042 port and setting a name.

  • Later, simply run the container with the name you chose.

https://github.com/khliland/IND320/blob/main/D2Dbook/images/Docker_images.png?raw=TRUE https://github.com/khliland/IND320/blob/main/D2Dbook/images/Docker_containers.png?raw=TRUE

Connect to the Cassandra cluster from Python.#

# Connecting to Cassandra
from cassandra.cluster import Cluster
cluster = Cluster(['localhost'], port=9042)
session = cluster.connect()

Keyspace#

  • In Cassandra database tables are stored in keyspaces (basically a distributed database).

  • These have parameters controlling their distribution on nodes/servers and redundancy.

  • We will use the simplest form locally.

# Set up new keyspace (first time only)
#                                              name of keyspace                        replication strategy           replication factor
session.execute("CREATE KEYSPACE IF NOT EXISTS my_first_keyspace WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };")
<cassandra.cluster.ResultSet at 0x105d841a0>

Create a table#

  • IF NOT EXISTS makes sure we do not overwrite existing tables

# Create a new table (first time only)
session.set_keyspace('my_first_keyspace')
session.execute("DROP TABLE IF EXISTS my_first_keyspace.my_first_table;") # Starting from scratch every time
session.execute("CREATE TABLE IF NOT EXISTS my_first_table (ind int PRIMARY KEY, company text, model text);")
<cassandra.cluster.ResultSet at 0x105da13d0>

Inserting and reading data#

# Insert some data (ind is the primary key, must be unique)
session.execute("INSERT INTO my_first_table (ind, company, model) VALUES (1, 'Tesla', 'Model S');")
session.execute("INSERT INTO my_first_table (ind, company, model) VALUES (2, 'Tesla', 'Model 3');")
session.execute("INSERT INTO my_first_table (ind, company, model) VALUES (3, 'Polestar', '3');")
<cassandra.cluster.ResultSet at 0x1104516a0>
# Query the data
rows = session.execute("SELECT * FROM my_first_table;")
for i in rows:
    print(i)
Row(ind=1, company='Tesla', model='Model S')
Row(ind=2, company='Tesla', model='Model 3')
Row(ind=3, company='Polestar', model='3')

Case sensitivity#

  • Cassandra is by default case insensitive in column names.

  • To use column names with capital letters, use double quotation marks both when creating tables and when inserting data.

  • The effect of insensitivity may be surprising.

    • Look carefully at the use of quotation marks and error message below.

session.set_keyspace('my_first_keyspace')
session.execute("DROP TABLE IF EXISTS my_first_keyspace.case_insensitive;") # Starting from scratch every time
session.execute("CREATE TABLE IF NOT EXISTS case_insensitive (Capital int PRIMARY KEY, Letters text, Everywhere text);")
session.execute("DROP TABLE IF EXISTS my_first_keyspace.case_sensitive;") # Starting from scratch every time
session.execute("CREATE TABLE IF NOT EXISTS case_sensitive (\"Capital\" int PRIMARY KEY, \"Letters\" text, \"Everywhere\" text);")
<cassandra.cluster.ResultSet at 0x11053b710>
session.execute("INSERT INTO case_insensitive (Capital, Letters, Everywhere) VALUES (1, 'Tesla', 'Model S');")
<cassandra.cluster.ResultSet at 0x105d6dd00>
session.execute("INSERT INTO case_sensitive (Capital, Letters, Everywhere) VALUES (1, 'Tesla', 'Model S');")
---------------------------------------------------------------------------
InvalidRequest                            Traceback (most recent call last)
Cell In[8], line 1
----> 1 session.execute("INSERT INTO case_sensitive (Capital, Letters, Everywhere) VALUES (1, 'Tesla', 'Model S');")

File ~/miniforge3/envs/IND320_2024/lib/python3.12/site-packages/cassandra/cluster.py:2677, in cassandra.cluster.Session.execute()

File ~/miniforge3/envs/IND320_2024/lib/python3.12/site-packages/cassandra/cluster.py:4956, in cassandra.cluster.ResponseFuture.result()

InvalidRequest: Error from server: code=2200 [Invalid query] message="Undefined column name capital in table my_first_keyspace.case_sensitive"
session.execute("INSERT INTO case_sensitive (\"Capital\", \"Letters\", \"Everywhere\") VALUES (1, 'Tesla', 'Model S');")
<cassandra.cluster.ResultSet at 0x1107ce3c0>
# Query the data
rows = session.execute("SELECT * FROM case_insensitive;")
for i in rows:
    print(i)
rows = session.execute("SELECT * FROM case_sensitive;")
for i in rows:
    print(i)
Row(capital=1, everywhere='Model S', letters='Tesla')
Row(Capital=1, Everywhere='Model S', Letters='Tesla')

Asyncronous writing#

  • If your application is very data intensive, waiting for a response is not productive.

  • Writing asyncronously sends the data but does not pause for reply.

session.execute_async("INSERT INTO my_first_table (ind, company, model) VALUES (4, 'Volkswagen', 'ID.4');")
<ResponseFuture: query='<SimpleStatement query="INSERT INTO my_first_table (ind, company, model) VALUES (4, 'Volkswagen', 'ID.4');", consistency=Not Set>' request_id=63 result=(no result yet) exception=None coordinator_host=None>
# Query the data
rows = session.execute("SELECT * FROM my_first_table;")
for i in rows:
    print(i)
Row(ind=1, company='Tesla', model='Model S')
Row(ind=2, company='Tesla', model='Model 3')
Row(ind=4, company='Volkswagen', model='ID.4')
Row(ind=3, company='Polestar', model='3')
# More specific query
prepared_statement = session.prepare("SELECT * FROM my_first_table WHERE company=? ALLOW FILTERING;")
teslas = session.execute(prepared_statement, ['Tesla'])
for i in teslas:
    print(i)
Row(ind=1, company='Tesla', model='Model S')
Row(ind=2, company='Tesla', model='Model 3')

Cassandra filtering#

Cassandra is inherently a distributed production database. Selecting as above may require downloading all data from a node, then filtering based on the WHERE part (only PRIMARY KEYs are centrally known). Solutions:

  • If the table is small or most of the data will satisfy the query, add ALLOW FILTERING at the end of the query (not recommended if not known).

  • Or make sure the WHERE clause points to one of the keys (see below).

# Create a new table (observe keys)
session.execute("DROP TABLE IF EXISTS my_first_keyspace.car_table;")
session.execute("CREATE TABLE IF NOT EXISTS car_table (company text, model text, PRIMARY KEY(company, model));")
<cassandra.cluster.ResultSet at 0x1107cf4a0>
# Insert some data (combination of company and model must be unique)
session.execute("INSERT INTO car_table (company, model) VALUES ('Tesla', 'Model S');")
session.execute("INSERT INTO car_table (company, model) VALUES ('Tesla', 'Model 3');")
session.execute("INSERT INTO car_table (company, model) VALUES ('Polestar', '3');")
session.execute("INSERT INTO car_table (company, model) VALUES ('Volkswagen', 'ID.4');")
<cassandra.cluster.ResultSet at 0x1107d6360>
# More specific query now works
prepared_statement = session.prepare("SELECT * FROM car_table WHERE company=?;")
teslas = session.execute(prepared_statement, ['Tesla'])
for i in teslas:
    print(i)
Row(company='Tesla', model='Model 3')
Row(company='Tesla', model='Model S')

Partitions#

  • Cassandra databases are usually replicated over different nodes.

  • Data is stored in partitions (subsets) which have local copys.

  • The primary key, e.g., PRIMARY KEY(company, model), is used in partitioning.

    • The first part, e.g., company, is most important.

    • All cars from a company will be located together, aiming for quicker queries.

Unique IDs#

  • In MySQL one could use the attribute AUTO_INCREMENT on integer IDs to automatically make a new unique index when inserting data.

  • This would cause unreasonable overhead in a distributed database.

  • UUIDs are used instead.

    • Universally Unique Identifiers are typically 128-bit random bit sequences with extremely low probability of duplication.

    • Cassandra uses a timeuuid type to combine a timestamp and uuid in one.

# Create a new table (first time only)
session.set_keyspace('my_first_keyspace')
session.execute("DROP TABLE IF EXISTS my_first_keyspace.table_with_uuid;")
session.execute("CREATE TABLE IF NOT EXISTS table_with_uuid (id timeuuid PRIMARY KEY, company text, model text, price float);")
<cassandra.cluster.ResultSet at 0x110840350>
session.execute("INSERT INTO table_with_uuid (id, company, model, price) VALUES (now(), 'Tesla', 'Model S', 20000.0);")
session.execute("INSERT INTO table_with_uuid (id, company, model, price) VALUES (now(), 'Tesla', 'Model S', 21000.0);")
session.execute("INSERT INTO table_with_uuid (id, company, model, price) VALUES (now(), 'Oldsmobile', 'Model 6C', 135000.0);")
<cassandra.cluster.ResultSet at 0x1107d7380>
from cassandra.util import datetime_from_uuid1

# Query the data
rows = session.execute("SELECT * FROM table_with_uuid;")
for i in rows:
    print(i)
    # Extract the timestamp from Cassandra's timeuuid
    print("Datetime:", datetime_from_uuid1(i.id))
Row(id=UUID('5496cd80-b27d-11ef-bd96-8f81262f2f14'), company='Tesla', model='Model S', price=21000.0)
Datetime: 2024-12-04 20:21:23.160000
Row(id=UUID('549742b0-b27d-11ef-bd96-8f81262f2f14'), company='Oldsmobile', model='Model 6C', price=135000.0)
Datetime: 2024-12-04 20:21:23.163000
Row(id=UUID('54956df0-b27d-11ef-bd96-8f81262f2f14'), company='Tesla', model='Model S', price=20000.0)
Datetime: 2024-12-04 20:21:23.151000

JSON in Cassandra#

Read previously saved JSON file forecast.json to memory#

import json
with open('../3_APIs/downloads/forecast.json', 'r') as f:
    forecast = json.load(f)
# Inspect JSON file
forecast.__str__()
"{'cod': '200', 'message': 0, 'cnt': 40, 'list': [{'dt': 1733324400, 'main': {'temp': 265.69, 'feels_like': 265.69, 'temp_min': 264.86, 'temp_max': 265.69, 'pressure': 1025, 'sea_level': 1025, 'grnd_level': 969, 'humidity': 87, 'temp_kf': 0.83}, 'weather': [{'id': 802, 'main': 'Clouds', 'description': 'scattered clouds', 'icon': '03n'}], 'clouds': {'all': 33}, 'wind': {'speed': 1.3, 'deg': 84, 'gust': 0.97}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-04 15:00:00'}, {'dt': 1733335200, 'main': {'temp': 264.62, 'feels_like': 264.62, 'temp_min': 263.88, 'temp_max': 264.62, 'pressure': 1023, 'sea_level': 1023, 'grnd_level': 967, 'humidity': 83, 'temp_kf': 0.74}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04n'}], 'clouds': {'all': 67}, 'wind': {'speed': 1, 'deg': 86, 'gust': 0.93}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-04 18:00:00'}, {'dt': 1733346000, 'main': {'temp': 263.22, 'feels_like': 263.22, 'temp_min': 263.22, 'temp_max': 263.22, 'pressure': 1022, 'sea_level': 1022, 'grnd_level': 967, 'humidity': 82, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 0.63, 'deg': 85, 'gust': 0.6}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-04 21:00:00'}, {'dt': 1733356800, 'main': {'temp': 263.21, 'feels_like': 263.21, 'temp_min': 263.21, 'temp_max': 263.21, 'pressure': 1022, 'sea_level': 1022, 'grnd_level': 967, 'humidity': 84, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 99}, 'wind': {'speed': 1.2, 'deg': 71, 'gust': 0.8}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 00:00:00'}, {'dt': 1733367600, 'main': {'temp': 262.18, 'feels_like': 257.6, 'temp_min': 262.18, 'temp_max': 262.18, 'pressure': 1020, 'sea_level': 1020, 'grnd_level': 965, 'humidity': 82, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.19, 'deg': 69, 'gust': 1.5}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 03:00:00'}, {'dt': 1733378400, 'main': {'temp': 263.48, 'feels_like': 259.02, 'temp_min': 263.48, 'temp_max': 263.48, 'pressure': 1018, 'sea_level': 1018, 'grnd_level': 963, 'humidity': 82, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.26, 'deg': 66, 'gust': 1.5}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 06:00:00'}, {'dt': 1733389200, 'main': {'temp': 264.57, 'feels_like': 259.63, 'temp_min': 264.57, 'temp_max': 264.57, 'pressure': 1015, 'sea_level': 1015, 'grnd_level': 961, 'humidity': 81, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.76, 'deg': 76, 'gust': 2.05}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 09:00:00'}, {'dt': 1733400000, 'main': {'temp': 263.81, 'feels_like': 257.74, 'temp_min': 263.81, 'temp_max': 263.81, 'pressure': 1014, 'sea_level': 1014, 'grnd_level': 959, 'humidity': 85, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04d'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.64, 'deg': 76, 'gust': 3.21}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-05 12:00:00'}, {'dt': 1733410800, 'main': {'temp': 264.03, 'feels_like': 257.91, 'temp_min': 264.03, 'temp_max': 264.03, 'pressure': 1012, 'sea_level': 1012, 'grnd_level': 957, 'humidity': 86, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.74, 'deg': 83, 'gust': 3.89}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 15:00:00'}, {'dt': 1733421600, 'main': {'temp': 263.69, 'feels_like': 257.83, 'temp_min': 263.69, 'temp_max': 263.69, 'pressure': 1010, 'sea_level': 1010, 'grnd_level': 956, 'humidity': 87, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.41, 'deg': 80, 'gust': 2.63}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 18:00:00'}, {'dt': 1733432400, 'main': {'temp': 264.38, 'feels_like': 258.14, 'temp_min': 264.38, 'temp_max': 264.38, 'pressure': 1009, 'sea_level': 1009, 'grnd_level': 954, 'humidity': 86, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.95, 'deg': 85, 'gust': 3.71}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 21:00:00'}, {'dt': 1733443200, 'main': {'temp': 264.78, 'feels_like': 259, 'temp_min': 264.78, 'temp_max': 264.78, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 953, 'humidity': 86, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.56, 'deg': 84, 'gust': 3.2}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 00:00:00'}, {'dt': 1733454000, 'main': {'temp': 266.56, 'feels_like': 261.68, 'temp_min': 266.56, 'temp_max': 266.56, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 952, 'humidity': 87, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.05, 'deg': 74, 'gust': 2.63}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 03:00:00'}, {'dt': 1733464800, 'main': {'temp': 268.02, 'feels_like': 264.55, 'temp_min': 268.02, 'temp_max': 268.02, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 952, 'humidity': 88, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.12, 'deg': 75, 'gust': 1.49}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 06:00:00'}, {'dt': 1733475600, 'main': {'temp': 269.72, 'feels_like': 267.67, 'temp_min': 269.72, 'temp_max': 269.72, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 952, 'humidity': 96, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.4, 'deg': 59, 'gust': 1.14}, 'pop': 1, 'snow': {'3h': 0.49}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 09:00:00'}, {'dt': 1733486400, 'main': {'temp': 270.46, 'feels_like': 270.46, 'temp_min': 270.46, 'temp_max': 270.46, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 953, 'humidity': 96, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13d'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.09, 'deg': 76, 'gust': 0.5}, 'visibility': 581, 'pop': 1, 'snow': {'3h': 0.64}, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-06 12:00:00'}, {'dt': 1733497200, 'main': {'temp': 268.53, 'feels_like': 265.1, 'temp_min': 268.53, 'temp_max': 268.53, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 954, 'humidity': 90, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 99}, 'wind': {'speed': 2.15, 'deg': 93, 'gust': 1.87}, 'visibility': 10000, 'pop': 0.2, 'snow': {'3h': 0.1}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 15:00:00'}, {'dt': 1733508000, 'main': {'temp': 267.48, 'feels_like': 264.73, 'temp_min': 267.48, 'temp_max': 267.48, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 953, 'humidity': 89, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.61, 'deg': 72, 'gust': 1.05}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 18:00:00'}, {'dt': 1733518800, 'main': {'temp': 269.9, 'feels_like': 267.67, 'temp_min': 269.9, 'temp_max': 269.9, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 953, 'humidity': 90, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.51, 'deg': 67, 'gust': 0.77}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 21:00:00'}, {'dt': 1733529600, 'main': {'temp': 270.93, 'feels_like': 270.93, 'temp_min': 270.93, 'temp_max': 270.93, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 954, 'humidity': 97, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 100}, 'wind': {'speed': 0.52, 'deg': 70, 'gust': 0.09}, 'visibility': 143, 'pop': 1, 'snow': {'3h': 1}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 00:00:00'}, {'dt': 1733540400, 'main': {'temp': 269, 'feels_like': 269, 'temp_min': 269, 'temp_max': 269, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 953, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 99}, 'wind': {'speed': 1.12, 'deg': 77, 'gust': 1.15}, 'visibility': 633, 'pop': 0.25, 'snow': {'3h': 0.26}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 03:00:00'}, {'dt': 1733551200, 'main': {'temp': 269.3, 'feels_like': 269.3, 'temp_min': 269.3, 'temp_max': 269.3, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 954, 'humidity': 95, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 99}, 'wind': {'speed': 1.06, 'deg': 74, 'gust': 0.63}, 'pop': 0.21, 'snow': {'3h': 0.19}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 06:00:00'}, {'dt': 1733562000, 'main': {'temp': 267.3, 'feels_like': 264.57, 'temp_min': 267.3, 'temp_max': 267.3, 'pressure': 1009, 'sea_level': 1009, 'grnd_level': 955, 'humidity': 93, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.58, 'deg': 83, 'gust': 1.32}, 'visibility': 10000, 'pop': 0.2, 'snow': {'3h': 0.14}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 09:00:00'}, {'dt': 1733572800, 'main': {'temp': 266.62, 'feels_like': 263.42, 'temp_min': 266.62, 'temp_max': 266.62, 'pressure': 1009, 'sea_level': 1009, 'grnd_level': 955, 'humidity': 94, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04d'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.79, 'deg': 70, 'gust': 1.4}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-07 12:00:00'}, {'dt': 1733583600, 'main': {'temp': 267.39, 'feels_like': 267.39, 'temp_min': 267.39, 'temp_max': 267.39, 'pressure': 1010, 'sea_level': 1010, 'grnd_level': 956, 'humidity': 94, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.32, 'deg': 68, 'gust': 0.99}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 15:00:00'}, {'dt': 1733594400, 'main': {'temp': 268.49, 'feels_like': 266.35, 'temp_min': 268.49, 'temp_max': 268.49, 'pressure': 1010, 'sea_level': 1010, 'grnd_level': 956, 'humidity': 93, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.36, 'deg': 66, 'gust': 1.1}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 18:00:00'}, {'dt': 1733605200, 'main': {'temp': 269.62, 'feels_like': 269.62, 'temp_min': 269.62, 'temp_max': 269.62, 'pressure': 1010, 'sea_level': 1010, 'grnd_level': 957, 'humidity': 91, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.27, 'deg': 70, 'gust': 0.95}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 21:00:00'}, {'dt': 1733616000, 'main': {'temp': 269.98, 'feels_like': 269.98, 'temp_min': 269.98, 'temp_max': 269.98, 'pressure': 1012, 'sea_level': 1012, 'grnd_level': 958, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 0.9, 'deg': 89, 'gust': 0.83}, 'visibility': 6669, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 00:00:00'}, {'dt': 1733626800, 'main': {'temp': 267.62, 'feels_like': 267.62, 'temp_min': 267.62, 'temp_max': 267.62, 'pressure': 1013, 'sea_level': 1013, 'grnd_level': 959, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 0.7, 'deg': 83, 'gust': 0.91}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 03:00:00'}, {'dt': 1733637600, 'main': {'temp': 265.26, 'feels_like': 265.26, 'temp_min': 265.26, 'temp_max': 265.26, 'pressure': 1015, 'sea_level': 1015, 'grnd_level': 961, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 89}, 'wind': {'speed': 0.93, 'deg': 89, 'gust': 1.25}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 06:00:00'}, {'dt': 1733648400, 'main': {'temp': 264.4, 'feels_like': 264.4, 'temp_min': 264.4, 'temp_max': 264.4, 'pressure': 1019, 'sea_level': 1019, 'grnd_level': 964, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04n'}], 'clouds': {'all': 61}, 'wind': {'speed': 1.12, 'deg': 91, 'gust': 1.3}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 09:00:00'}, {'dt': 1733659200, 'main': {'temp': 266.18, 'feels_like': 262.78, 'temp_min': 266.18, 'temp_max': 266.18, 'pressure': 1020, 'sea_level': 1020, 'grnd_level': 965, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04d'}], 'clouds': {'all': 80}, 'wind': {'speed': 1.87, 'deg': 64, 'gust': 1.79}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-08 12:00:00'}, {'dt': 1733670000, 'main': {'temp': 264.32, 'feels_like': 264.32, 'temp_min': 264.32, 'temp_max': 264.32, 'pressure': 1023, 'sea_level': 1023, 'grnd_level': 968, 'humidity': 90, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 88}, 'wind': {'speed': 1.33, 'deg': 82, 'gust': 1.69}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 15:00:00'}, {'dt': 1733680800, 'main': {'temp': 264.23, 'feels_like': 264.23, 'temp_min': 264.23, 'temp_max': 264.23, 'pressure': 1026, 'sea_level': 1026, 'grnd_level': 971, 'humidity': 89, 'temp_kf': 0}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04n'}], 'clouds': {'all': 74}, 'wind': {'speed': 0.92, 'deg': 91, 'gust': 1.53}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 18:00:00'}, {'dt': 1733691600, 'main': {'temp': 263.47, 'feels_like': 263.47, 'temp_min': 263.47, 'temp_max': 263.47, 'pressure': 1029, 'sea_level': 1029, 'grnd_level': 974, 'humidity': 89, 'temp_kf': 0}, 'weather': [{'id': 802, 'main': 'Clouds', 'description': 'scattered clouds', 'icon': '03n'}], 'clouds': {'all': 35}, 'wind': {'speed': 0.63, 'deg': 90, 'gust': 1.12}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 21:00:00'}, {'dt': 1733702400, 'main': {'temp': 263.78, 'feels_like': 263.78, 'temp_min': 263.78, 'temp_max': 263.78, 'pressure': 1032, 'sea_level': 1032, 'grnd_level': 976, 'humidity': 94, 'temp_kf': 0}, 'weather': [{'id': 802, 'main': 'Clouds', 'description': 'scattered clouds', 'icon': '03n'}], 'clouds': {'all': 33}, 'wind': {'speed': 0.58, 'deg': 124, 'gust': 0.83}, 'visibility': 9520, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-09 00:00:00'}, {'dt': 1733713200, 'main': {'temp': 268.57, 'feels_like': 268.57, 'temp_min': 268.57, 'temp_max': 268.57, 'pressure': 1032, 'sea_level': 1032, 'grnd_level': 977, 'humidity': 96, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 84}, 'wind': {'speed': 0.66, 'deg': 11, 'gust': 0.51}, 'visibility': 405, 'pop': 0.78, 'snow': {'3h': 0.37}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-09 03:00:00'}, {'dt': 1733724000, 'main': {'temp': 270.31, 'feels_like': 270.31, 'temp_min': 270.31, 'temp_max': 270.31, 'pressure': 1033, 'sea_level': 1033, 'grnd_level': 978, 'humidity': 96, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 92}, 'wind': {'speed': 0.41, 'deg': 196, 'gust': 0.47}, 'visibility': 649, 'pop': 0.96, 'snow': {'3h': 0.74}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-09 06:00:00'}, {'dt': 1733734800, 'main': {'temp': 272.34, 'feels_like': 272.34, 'temp_min': 272.34, 'temp_max': 272.34, 'pressure': 1033, 'sea_level': 1033, 'grnd_level': 979, 'humidity': 98, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.26, 'deg': 255, 'gust': 1.66}, 'visibility': 511, 'pop': 1, 'snow': {'3h': 0.93}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-09 09:00:00'}, {'dt': 1733745600, 'main': {'temp': 275.08, 'feels_like': 272.76, 'temp_min': 275.08, 'temp_max': 275.08, 'pressure': 1032, 'sea_level': 1032, 'grnd_level': 978, 'humidity': 98, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13d'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.16, 'deg': 241, 'gust': 3.19}, 'visibility': 94, 'pop': 1, 'snow': {'3h': 0.66}, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-09 12:00:00'}], 'city': {'id': 3145614, 'name': 'Mo i Rana', 'coord': {'lat': 66.3128, 'lon': 14.1428}, 'country': 'NO', 'population': 17853, 'timezone': 3600, 'sunrise': 1733303288, 'sunset': 1733315984}}"

Raw JSON#

  • A simple, but not very efficient way of storing JSON data is to treat it as a text and save it directly to the database.

  • More efficient, with regard to transfer, is to compress the JSON data to a blob first.

    • Compression is automatic.

# Create a new table which treats the whole JSON as a blob, using the city id and the first dt as keys
session.set_keyspace('my_first_keyspace')
session.execute("DROP TABLE IF EXISTS my_first_keyspace.forecast_table;")
session.execute("CREATE TABLE IF NOT EXISTS forecast_table (city_id int, dt int, forecast blob, PRIMARY KEY(city_id, dt));")
<cassandra.cluster.ResultSet at 0x1074b49b0>

Insert the forecast data into the table as text blob#

session.execute("INSERT INTO forecast_table (city_id, dt, forecast) VALUES (%s, %s, textAsBlob(%s));", (forecast['city']['id'], forecast['list'][0]['dt'], forecast.__str__()))
<cassandra.cluster.ResultSet at 0x105d5e3f0>
# Query the data
forecast_rows = session.execute("SELECT * FROM forecast_table;")
print(forecast_rows.one()) # <- only one row
Row(city_id=3145614, dt=1733324400, forecast=b"{'cod': '200', 'message': 0, 'cnt': 40, 'list': [{'dt': 1733324400, 'main': {'temp': 265.69, 'feels_like': 265.69, 'temp_min': 264.86, 'temp_max': 265.69, 'pressure': 1025, 'sea_level': 1025, 'grnd_level': 969, 'humidity': 87, 'temp_kf': 0.83}, 'weather': [{'id': 802, 'main': 'Clouds', 'description': 'scattered clouds', 'icon': '03n'}], 'clouds': {'all': 33}, 'wind': {'speed': 1.3, 'deg': 84, 'gust': 0.97}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-04 15:00:00'}, {'dt': 1733335200, 'main': {'temp': 264.62, 'feels_like': 264.62, 'temp_min': 263.88, 'temp_max': 264.62, 'pressure': 1023, 'sea_level': 1023, 'grnd_level': 967, 'humidity': 83, 'temp_kf': 0.74}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04n'}], 'clouds': {'all': 67}, 'wind': {'speed': 1, 'deg': 86, 'gust': 0.93}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-04 18:00:00'}, {'dt': 1733346000, 'main': {'temp': 263.22, 'feels_like': 263.22, 'temp_min': 263.22, 'temp_max': 263.22, 'pressure': 1022, 'sea_level': 1022, 'grnd_level': 967, 'humidity': 82, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 0.63, 'deg': 85, 'gust': 0.6}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-04 21:00:00'}, {'dt': 1733356800, 'main': {'temp': 263.21, 'feels_like': 263.21, 'temp_min': 263.21, 'temp_max': 263.21, 'pressure': 1022, 'sea_level': 1022, 'grnd_level': 967, 'humidity': 84, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 99}, 'wind': {'speed': 1.2, 'deg': 71, 'gust': 0.8}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 00:00:00'}, {'dt': 1733367600, 'main': {'temp': 262.18, 'feels_like': 257.6, 'temp_min': 262.18, 'temp_max': 262.18, 'pressure': 1020, 'sea_level': 1020, 'grnd_level': 965, 'humidity': 82, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.19, 'deg': 69, 'gust': 1.5}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 03:00:00'}, {'dt': 1733378400, 'main': {'temp': 263.48, 'feels_like': 259.02, 'temp_min': 263.48, 'temp_max': 263.48, 'pressure': 1018, 'sea_level': 1018, 'grnd_level': 963, 'humidity': 82, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.26, 'deg': 66, 'gust': 1.5}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 06:00:00'}, {'dt': 1733389200, 'main': {'temp': 264.57, 'feels_like': 259.63, 'temp_min': 264.57, 'temp_max': 264.57, 'pressure': 1015, 'sea_level': 1015, 'grnd_level': 961, 'humidity': 81, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.76, 'deg': 76, 'gust': 2.05}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 09:00:00'}, {'dt': 1733400000, 'main': {'temp': 263.81, 'feels_like': 257.74, 'temp_min': 263.81, 'temp_max': 263.81, 'pressure': 1014, 'sea_level': 1014, 'grnd_level': 959, 'humidity': 85, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04d'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.64, 'deg': 76, 'gust': 3.21}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-05 12:00:00'}, {'dt': 1733410800, 'main': {'temp': 264.03, 'feels_like': 257.91, 'temp_min': 264.03, 'temp_max': 264.03, 'pressure': 1012, 'sea_level': 1012, 'grnd_level': 957, 'humidity': 86, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.74, 'deg': 83, 'gust': 3.89}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 15:00:00'}, {'dt': 1733421600, 'main': {'temp': 263.69, 'feels_like': 257.83, 'temp_min': 263.69, 'temp_max': 263.69, 'pressure': 1010, 'sea_level': 1010, 'grnd_level': 956, 'humidity': 87, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.41, 'deg': 80, 'gust': 2.63}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 18:00:00'}, {'dt': 1733432400, 'main': {'temp': 264.38, 'feels_like': 258.14, 'temp_min': 264.38, 'temp_max': 264.38, 'pressure': 1009, 'sea_level': 1009, 'grnd_level': 954, 'humidity': 86, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.95, 'deg': 85, 'gust': 3.71}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-05 21:00:00'}, {'dt': 1733443200, 'main': {'temp': 264.78, 'feels_like': 259, 'temp_min': 264.78, 'temp_max': 264.78, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 953, 'humidity': 86, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.56, 'deg': 84, 'gust': 3.2}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 00:00:00'}, {'dt': 1733454000, 'main': {'temp': 266.56, 'feels_like': 261.68, 'temp_min': 266.56, 'temp_max': 266.56, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 952, 'humidity': 87, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 3.05, 'deg': 74, 'gust': 2.63}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 03:00:00'}, {'dt': 1733464800, 'main': {'temp': 268.02, 'feels_like': 264.55, 'temp_min': 268.02, 'temp_max': 268.02, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 952, 'humidity': 88, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.12, 'deg': 75, 'gust': 1.49}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 06:00:00'}, {'dt': 1733475600, 'main': {'temp': 269.72, 'feels_like': 267.67, 'temp_min': 269.72, 'temp_max': 269.72, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 952, 'humidity': 96, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.4, 'deg': 59, 'gust': 1.14}, 'pop': 1, 'snow': {'3h': 0.49}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 09:00:00'}, {'dt': 1733486400, 'main': {'temp': 270.46, 'feels_like': 270.46, 'temp_min': 270.46, 'temp_max': 270.46, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 953, 'humidity': 96, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13d'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.09, 'deg': 76, 'gust': 0.5}, 'visibility': 581, 'pop': 1, 'snow': {'3h': 0.64}, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-06 12:00:00'}, {'dt': 1733497200, 'main': {'temp': 268.53, 'feels_like': 265.1, 'temp_min': 268.53, 'temp_max': 268.53, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 954, 'humidity': 90, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 99}, 'wind': {'speed': 2.15, 'deg': 93, 'gust': 1.87}, 'visibility': 10000, 'pop': 0.2, 'snow': {'3h': 0.1}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 15:00:00'}, {'dt': 1733508000, 'main': {'temp': 267.48, 'feels_like': 264.73, 'temp_min': 267.48, 'temp_max': 267.48, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 953, 'humidity': 89, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.61, 'deg': 72, 'gust': 1.05}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 18:00:00'}, {'dt': 1733518800, 'main': {'temp': 269.9, 'feels_like': 267.67, 'temp_min': 269.9, 'temp_max': 269.9, 'pressure': 1006, 'sea_level': 1006, 'grnd_level': 953, 'humidity': 90, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.51, 'deg': 67, 'gust': 0.77}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-06 21:00:00'}, {'dt': 1733529600, 'main': {'temp': 270.93, 'feels_like': 270.93, 'temp_min': 270.93, 'temp_max': 270.93, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 954, 'humidity': 97, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 100}, 'wind': {'speed': 0.52, 'deg': 70, 'gust': 0.09}, 'visibility': 143, 'pop': 1, 'snow': {'3h': 1}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 00:00:00'}, {'dt': 1733540400, 'main': {'temp': 269, 'feels_like': 269, 'temp_min': 269, 'temp_max': 269, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 953, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 99}, 'wind': {'speed': 1.12, 'deg': 77, 'gust': 1.15}, 'visibility': 633, 'pop': 0.25, 'snow': {'3h': 0.26}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 03:00:00'}, {'dt': 1733551200, 'main': {'temp': 269.3, 'feels_like': 269.3, 'temp_min': 269.3, 'temp_max': 269.3, 'pressure': 1007, 'sea_level': 1007, 'grnd_level': 954, 'humidity': 95, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 99}, 'wind': {'speed': 1.06, 'deg': 74, 'gust': 0.63}, 'pop': 0.21, 'snow': {'3h': 0.19}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 06:00:00'}, {'dt': 1733562000, 'main': {'temp': 267.3, 'feels_like': 264.57, 'temp_min': 267.3, 'temp_max': 267.3, 'pressure': 1009, 'sea_level': 1009, 'grnd_level': 955, 'humidity': 93, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.58, 'deg': 83, 'gust': 1.32}, 'visibility': 10000, 'pop': 0.2, 'snow': {'3h': 0.14}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 09:00:00'}, {'dt': 1733572800, 'main': {'temp': 266.62, 'feels_like': 263.42, 'temp_min': 266.62, 'temp_max': 266.62, 'pressure': 1009, 'sea_level': 1009, 'grnd_level': 955, 'humidity': 94, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04d'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.79, 'deg': 70, 'gust': 1.4}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-07 12:00:00'}, {'dt': 1733583600, 'main': {'temp': 267.39, 'feels_like': 267.39, 'temp_min': 267.39, 'temp_max': 267.39, 'pressure': 1010, 'sea_level': 1010, 'grnd_level': 956, 'humidity': 94, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.32, 'deg': 68, 'gust': 0.99}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 15:00:00'}, {'dt': 1733594400, 'main': {'temp': 268.49, 'feels_like': 266.35, 'temp_min': 268.49, 'temp_max': 268.49, 'pressure': 1010, 'sea_level': 1010, 'grnd_level': 956, 'humidity': 93, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.36, 'deg': 66, 'gust': 1.1}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 18:00:00'}, {'dt': 1733605200, 'main': {'temp': 269.62, 'feels_like': 269.62, 'temp_min': 269.62, 'temp_max': 269.62, 'pressure': 1010, 'sea_level': 1010, 'grnd_level': 957, 'humidity': 91, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.27, 'deg': 70, 'gust': 0.95}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-07 21:00:00'}, {'dt': 1733616000, 'main': {'temp': 269.98, 'feels_like': 269.98, 'temp_min': 269.98, 'temp_max': 269.98, 'pressure': 1012, 'sea_level': 1012, 'grnd_level': 958, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 0.9, 'deg': 89, 'gust': 0.83}, 'visibility': 6669, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 00:00:00'}, {'dt': 1733626800, 'main': {'temp': 267.62, 'feels_like': 267.62, 'temp_min': 267.62, 'temp_max': 267.62, 'pressure': 1013, 'sea_level': 1013, 'grnd_level': 959, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 100}, 'wind': {'speed': 0.7, 'deg': 83, 'gust': 0.91}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 03:00:00'}, {'dt': 1733637600, 'main': {'temp': 265.26, 'feels_like': 265.26, 'temp_min': 265.26, 'temp_max': 265.26, 'pressure': 1015, 'sea_level': 1015, 'grnd_level': 961, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 89}, 'wind': {'speed': 0.93, 'deg': 89, 'gust': 1.25}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 06:00:00'}, {'dt': 1733648400, 'main': {'temp': 264.4, 'feels_like': 264.4, 'temp_min': 264.4, 'temp_max': 264.4, 'pressure': 1019, 'sea_level': 1019, 'grnd_level': 964, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04n'}], 'clouds': {'all': 61}, 'wind': {'speed': 1.12, 'deg': 91, 'gust': 1.3}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 09:00:00'}, {'dt': 1733659200, 'main': {'temp': 266.18, 'feels_like': 262.78, 'temp_min': 266.18, 'temp_max': 266.18, 'pressure': 1020, 'sea_level': 1020, 'grnd_level': 965, 'humidity': 92, 'temp_kf': 0}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04d'}], 'clouds': {'all': 80}, 'wind': {'speed': 1.87, 'deg': 64, 'gust': 1.79}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-08 12:00:00'}, {'dt': 1733670000, 'main': {'temp': 264.32, 'feels_like': 264.32, 'temp_min': 264.32, 'temp_max': 264.32, 'pressure': 1023, 'sea_level': 1023, 'grnd_level': 968, 'humidity': 90, 'temp_kf': 0}, 'weather': [{'id': 804, 'main': 'Clouds', 'description': 'overcast clouds', 'icon': '04n'}], 'clouds': {'all': 88}, 'wind': {'speed': 1.33, 'deg': 82, 'gust': 1.69}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 15:00:00'}, {'dt': 1733680800, 'main': {'temp': 264.23, 'feels_like': 264.23, 'temp_min': 264.23, 'temp_max': 264.23, 'pressure': 1026, 'sea_level': 1026, 'grnd_level': 971, 'humidity': 89, 'temp_kf': 0}, 'weather': [{'id': 803, 'main': 'Clouds', 'description': 'broken clouds', 'icon': '04n'}], 'clouds': {'all': 74}, 'wind': {'speed': 0.92, 'deg': 91, 'gust': 1.53}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 18:00:00'}, {'dt': 1733691600, 'main': {'temp': 263.47, 'feels_like': 263.47, 'temp_min': 263.47, 'temp_max': 263.47, 'pressure': 1029, 'sea_level': 1029, 'grnd_level': 974, 'humidity': 89, 'temp_kf': 0}, 'weather': [{'id': 802, 'main': 'Clouds', 'description': 'scattered clouds', 'icon': '03n'}], 'clouds': {'all': 35}, 'wind': {'speed': 0.63, 'deg': 90, 'gust': 1.12}, 'visibility': 10000, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-08 21:00:00'}, {'dt': 1733702400, 'main': {'temp': 263.78, 'feels_like': 263.78, 'temp_min': 263.78, 'temp_max': 263.78, 'pressure': 1032, 'sea_level': 1032, 'grnd_level': 976, 'humidity': 94, 'temp_kf': 0}, 'weather': [{'id': 802, 'main': 'Clouds', 'description': 'scattered clouds', 'icon': '03n'}], 'clouds': {'all': 33}, 'wind': {'speed': 0.58, 'deg': 124, 'gust': 0.83}, 'visibility': 9520, 'pop': 0, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-09 00:00:00'}, {'dt': 1733713200, 'main': {'temp': 268.57, 'feels_like': 268.57, 'temp_min': 268.57, 'temp_max': 268.57, 'pressure': 1032, 'sea_level': 1032, 'grnd_level': 977, 'humidity': 96, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 84}, 'wind': {'speed': 0.66, 'deg': 11, 'gust': 0.51}, 'visibility': 405, 'pop': 0.78, 'snow': {'3h': 0.37}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-09 03:00:00'}, {'dt': 1733724000, 'main': {'temp': 270.31, 'feels_like': 270.31, 'temp_min': 270.31, 'temp_max': 270.31, 'pressure': 1033, 'sea_level': 1033, 'grnd_level': 978, 'humidity': 96, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 92}, 'wind': {'speed': 0.41, 'deg': 196, 'gust': 0.47}, 'visibility': 649, 'pop': 0.96, 'snow': {'3h': 0.74}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-09 06:00:00'}, {'dt': 1733734800, 'main': {'temp': 272.34, 'feels_like': 272.34, 'temp_min': 272.34, 'temp_max': 272.34, 'pressure': 1033, 'sea_level': 1033, 'grnd_level': 979, 'humidity': 98, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13n'}], 'clouds': {'all': 100}, 'wind': {'speed': 1.26, 'deg': 255, 'gust': 1.66}, 'visibility': 511, 'pop': 1, 'snow': {'3h': 0.93}, 'sys': {'pod': 'n'}, 'dt_txt': '2024-12-09 09:00:00'}, {'dt': 1733745600, 'main': {'temp': 275.08, 'feels_like': 272.76, 'temp_min': 275.08, 'temp_max': 275.08, 'pressure': 1032, 'sea_level': 1032, 'grnd_level': 978, 'humidity': 98, 'temp_kf': 0}, 'weather': [{'id': 600, 'main': 'Snow', 'description': 'light snow', 'icon': '13d'}], 'clouds': {'all': 100}, 'wind': {'speed': 2.16, 'deg': 241, 'gust': 3.19}, 'visibility': 94, 'pop': 1, 'snow': {'3h': 0.66}, 'sys': {'pod': 'd'}, 'dt_txt': '2024-12-09 12:00:00'}], 'city': {'id': 3145614, 'name': 'Mo i Rana', 'coord': {'lat': 66.3128, 'lon': 14.1428}, 'country': 'NO', 'population': 17853, 'timezone': 3600, 'sunrise': 1733303288, 'sunset': 1733315984}}")