RethinkDB - goddes4/python-study-wiki GitHub Wiki

When is RethinkDB a good choice?

RethinkDB is a great choice when your applications could benefit from realtime feeds to your data.

  • Collaborative web and mobile apps
  • Streaming analytics apps
  • Multiplayer games
  • Realtime marketplaces
  • Connected devices

When is RethinkDB not a good choice?

  • RethinkDB is not a good choice if you need full ACID support or strong schema enforcementโ€”in this case you are better off using a relational database such as MySQL or PostgreSQL.
  • If you are doing deep, computationally-intensive analytics you are better off using a system like Hadoop or a column-oriented store like Vertica.
  • In some cases RethinkDB trades off write availability in favor of data consistency. If high write availability is critical and you donโ€™t mind dealing with conflicts you may be better off with a Dynamo-style system like Riak.

Install and Run

Install the server (Ubuntu)

source /etc/lsb-release && echo "deb http://download.rethinkdb.com/apt $DISTRIB_CODENAME main" | sudo tee /etc/apt/sources.list.d/rethinkdb.list
wget -qO- http://download.rethinkdb.com/apt/pubkey.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install rethinkdb

Install the python driver

pip install rethinkdb

Start the server

$ rethinkdb
info: Creating directory /home/user/rethinkdb_data
info: Listening for intracluster connections on port 29015
info: Listening for client driver connections on port 28015
info: Listening for administrative HTTP connections on port 8080
info: Server ready

Multiple RethinkDB instances on a single machine

ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ์ด ์ด๋ฃจ์–ด์ง€๋ฉด,

  1. ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ด์šฉํ•˜์—ฌ localhost:8080 ๋˜๋Š” localhost:8081 ์— ์ ‘์†ํ•ด ์„œ๋ฒ„ ํ˜„ํ™ฉ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  2. ํด๋ผ์ด์–ธํŠธ๋Š” localhost:28015 ๋˜๋Š” localhost:28016 ์— ์—ฐ๊ฒฐํ•˜์—ฌ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
$ rethinkdb --port-offset 1 --directory rethinkdb_data2 --join localhost:29015
info: Creating directory /home/user/rethinkdb_data2
info: Listening for intracluster connections on port 29016
info: Attempting connection to 1 peer...
info: Connected to server "Chaosknight" e6bfec5c-861e-4a8c-8eed-604cc124b714
info: Listening for client driver connections on port 28016
info: Listening for administrative HTTP connections on port 8081
info: Server ready

A RethinkDB cluster using multiple machines

first machine

$ rethinkdb --bind all

second machine

$ rethinkdb --join IP_OF_FIRST_MACHINE:29015 --bind all

์ฃผ์š” ์˜ต์…˜

  • --bind all : ์„œ๋ฒ„๊ฐ€ ๋ฐ”์ธ๋”ฉํ•  ์•„์ดํ”ผ ์ฃผ์†Œ
  • --http-port 8081 : ์›น ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€ ํฌํŠธ
  • --port-offset 1 : ๋‹จ์ผ ๋ฌผ๋ฆฌ ์„œ๋ฒ„์—์„œ ๋‹ค์ค‘ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹คํ–‰ํ•  ๊ฒฝ์šฐ ํฌํŠธ๊ฐ€ ๊ฒน์น˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์ฆ๊ฐ€ํ•˜๋Š” ํฌํŠธ ๊ฐ’
  • --directory rethinkdb_data2 : rethinkdb ๊ฐ€ ์‚ฌ์šฉํ•  ๋””๋ ‰ํ† ๋ฆฌ ์ง€์ • (๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค์™€ ๊ฒน์น˜๋ฉด ์•ˆ๋จ)
  • --join localhost:29015 : ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ฉ๋ฅ˜๋ฅผ ์‹œ๋„ํ•  ๊ธฐ์กด ์ธ์Šคํ„ด์Šค ์ฃผ์†Œ

RethinkDB Guide in python

Import the driver

import rethinkdb as r

Open a connection

conn = r.connect('localhost', 28015)
conn.use('taeyo_db')

or

r.connect(db='taeyo_db').repl()

Manipulating databases

r.db_create('taeyo_db').run(conn)
r.db_drop('taeyo_db').run(conn)
r.db_list().run(conn)

Manipulating tables

r.db("taeyo_db").table_create('authors').run(conn)
r.db("taeyo_db").table_drop('authors').run(conn)
r.db("taeyo_db").table_list().run(conn)

r.table('authors').index_create('post_id').run(conn)
r.table('authors').index_drop('post_id').run(conn)
r.table('authors').index_list().run(conn)
r.table('authors').index_rename('post_id', 'message_id').run(conn)
r.table('authors').index_status().run(conn)

The result will be:

{
    "config_changes": [
        <table configuration data>
    ],
    "tables_created": 1
}

Insert data

r.table("authors").insert([
    { "name": "William Adama", "tv_show": "Battlestar Galactica",
      "posts": [
        {"title": "Decommissioning speech", "content": "The Cylon War is long over..."},
        {"title": "We are at war", "content": "Moments ago, this ship received..."},
        {"title": "The new Earth", "content": "The discoveries of the past few days..."}
      ]
    },
    { "name": "Laura Roslin", "tv_show": "Battlestar Galactica",
      "posts": [
        {"title": "The oath of office", "content": "I, Laura Roslin, ..."},
        {"title": "They look like us", "content": "The Cylons have the ability..."}
      ]
    },
    { "name": "Jean-Luc Picard", "tv_show": "Star Trek TNG",
      "posts": [
        {"title": "Civil rights", "content": "There are some words I've known since..."}
      ]
    }
]).run(conn)

The result will be:

{
    "unchanged": 0,
    "skipped": 0,
    "replaced": 0,
    "inserted": 3,
    "generated_keys": [
        "7644aaf2-9928-4231-aa68-4e65e31bf219",
        "064058b6-cea9-4117-b92d-c911027a725a",
        "543ad9c8-1744-4001-bb5e-450b2565d02c"
    ],
    "errors": 0,
    "deleted": 0
}

Retrieve documents

All documents in a table
cursor = r.table("authors").run()
for document in cursor:
    print(document)
Filter documents based on a condition
cursor = r.table("authors").filter(r.row["name"] == "William Adama").run()
for document in cursor:
    print(document)
Retrieve documents by primary key

This way we can retrieve the document directly without iterating through a cursor.

r.db('test').table('authors').get('7644aaf2-9928-4231-aa68-4e65e31bf219').run()

Realtime feeds

cursor = r.table("authors").changes().run()
for document in cursor:
    print(document)

The code above will print the following messages in the second terminal:

{
  "new_val": {
    "id": "1d854219-85c6-4e6c-8259-dbda0ab386d4",
    "name": "Laura Roslin",
    "posts": [...],
    "tv_show": "Battlestar Galactica",
    "type": "fictional"
  },
  "old_val": {
    "id": "1d854219-85c6-4e6c-8259-dbda0ab386d4",
    "name": "Laura Roslin",
    "posts": [...],
    "tv_show": "Battlestar Galactica"
  }
}

Update documents

Updating All documents in a table
r.table("authors").update({"type": "fictional"}).run()

The result will be:

{
    "unchanged": 0,
    "skipped": 0,
    "replaced": 3,
    "inserted": 0,
    "errors": 0,
    "deleted":0
}
Updating William Adama's record
r.table("authors").
    filter(r.row['name'] == "William Adama").
    update({"rank": "Admiral"}).run()

The result will be:

{
    "unchanged": 0,
    "skipped": 0,
    "replaced": 1,
    "inserted": 0,
    "errors": 0,
    "deleted": 0
}

Delete documents

r.table("authors").
    filter( r.row["posts"].count() < 3 ).
    delete().run()

The result will be:

{
    "unchanged": 0,
    "skipped": 0,
    "replaced": 0,
    "inserted": 0,
    "errors": 0,
    "deleted": 2
}