cassandra-driver-python

此文参考cassandra driver 3.8.1文档,参考原文的结构,链接地址:
cassandra-driver-3.8.1
详细文档

开始

确保安装正确的驱动模块(cassandra-driver),可以通过pip安装。

连接cassandra

连接数据库(cassandra下同),必须确保有安装Cluster模块。正常情况下,本文中使用到的模块,安装 cassandra-driver中已有。
如果使用非标准的端口(9042)或使用SSL方式连接,或自定义一些驱动操作,还需要引入DCAwareRoundRobinPolicy模块

from cassandra.cluster import Cluster #引入Cluster模块
from cassandra.polices import DCAwareRoundRobinPolicy#引入DCAwareRoundRobinPolicy模块
cluster = Cluster()#连接本地数据库
cluster = Cluster(['127.0.0.1'])#连接本地数据库
cluster = Cluster(['1.1.1.1','1.1.1.2'])#连接两台机器的数据库
cluster = Cluster(['1.1.1.1', '1.1.1.2', '1.1.1.3'],
load_balancing_policy=DCAwareRoundRobinPolicy(local_dc='US_EAST'), port=8888)#连接三台机器的数据库,且指定端口为8888

创建了Cluster后,并不会自动连接上数据库,需要我们执行连接操作。

session = cluster.connect()#简单的连接
session = cluster.connect('keyspacename')#指定连接keyspace,相当于sql中use dbname
session.set_keyspace('otherkeyspace') #设置、修改keyspace
session.execute('use keyspacename')#设置、修改keyspace

查询操作

查询操作使用execute(),将cql语句拼接作为参数传入即可。

rows = session.execute('select * from table1') #查询所有列
rows = session.execute('select name,age,email from table1')#查询指定列
for row in rows: #遍历查询的结果
    print(row.name+row.age+row.email)
    print(row[0]+row[1]+row[2]) 
for (name,age,email) in rows:#遍历查询的结果
    print(name+age+email)

传参查询

支持两种传参查询操作:位置和名字。

  • 位置
    使用%s来传递

    session.execute(
    """
    INSERT INTO users (name, credits, user_id)
    VALUES (%s, %s, %s)
    """,
    ("hmh", 30, uuid.uuid1())
    )

    这里对所有类型的参数都使用%s,如果想传入字符%,使用%%。在传递序列时,必须有第二值(第一个值后面加,)。

    session.execute("INSERT INTO foo (bar) VALUES (%s)", ("blah", ))  # 末尾要加,
    session.execute("INSERT INTO foo (bar) VALUES (%s)", ["blah"])  
  • 名字
    可以使用相同名称的占位符。通常只用这种方式传递数据值,像keyspace名、表名、列名必须在开始就设定好。

    session.execute(
    """
    INSERT INTO users (name, credits, user_id, username)
    VALUES (%(name)s, %(credits)s, %(user_id)s, %(name)s)
    """,{'name': "John O'Reilly", 'credits': 42, 'user_id': uuid.uuid1()})
    
    #注意占位符(name)使用了两次
    

类型转换


  • python类型 ———–CQL类型
  • None ———–NULL
  • bool ———–boolean
  • float ———–float、double
  • int、long ———–int、bigint、varint、smallint、tinyint、counter
  • decimal.Decimal ———–decimal
  • str、unicode ———–ascii
  • buffer、bytearray ———–blob
  • date ———–date
  • datetime ———–timestamp
  • time ———–time
  • list、tuple、generator ———–list
  • set、frozenset ———– set
  • dict、OrderedDict ———–map
  • uuid.UUID ———–uuid

异步查询

驱动支持异步查询,对应方法是execute_async()。相比于等侍查询完成返回结果,这个方法会立即返回一个ResponseFuture对象。有两个方法可以从ResponseFuture对象中取得结果。

  • 调用result()方法。如果查询还没有结束,它将会阻塞直至有结果时并返回结果,或错误发生时返回异常。
 from cassandra import ReadTimeout # 引入ReadTimeout模块
query = "SELECT * FROM users WHERE user_id=%s"
future = session.execute_async(query, [user_id])#异步查询做其它工作
try:
    rows = future.result()#读查询结果
    user = rows[0]
    print(user.name+user.age)
except ReadTimeout:#出现异常的情况
    log.exception("Query timed out:")

还可以同时执行多个查询:

futures = []
query = "SELECT * FROM users WHERE user_id=%s"
for user_id in ids_to_fetch:#将所有查询加入列表
    futures.append(session.execute_async(query, [user_id])
 #执行其它操作 
for future in futures:
    rows = future.result()
    print(rows[0].name
  • 调用回调方法,有add_callback(), add_errback(), 和 add_callbacks()。如果你以前使用过Twisted python,这个设计将是一个非常简单的版本。
def handle_success(rows):#定义成功操作
    user = rows[0]
    try:
        process_user(user.name, user.age, user.id)
    except Exception:
        log.error("Failed to process user %s", user.id)
        # don't re-raise errors in the callback

def handle_error(exception):#定义错误处理
    log.error("Failed to fetch user info: %s", exception)
future = session.execute_async(query)#执行异步查询
future.add_callbacks(handle_success, handle_error)

需要注意两点:
1、任何回调函数内部的异常将会被记录并忽略处理;
2、回调运行在事件循环线程,因此长任务操作将会阻止其它请求的处理。

设置一致性水平

一致性等级是用来确定一次成功的查询,需要多少数量副本对查询有响应。默认的查询的一致性等级是ConsistencyLevel.LOCAL_ONE,当然你可以通过Session.default_consistency_level设定想要等级。为了为每个请求指定不同的一致性等级,需要包装查询在SimpleStatement中:

from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement
query = SimpleStatement(
    "INSERT INTO users (name, age) VALUES (%s, %s)",
    consistency_level=ConsistencyLevel.QUORUM)#设置等级水平
session.execute(query, ('John', 42))#执行查询

Prepared Statements

Prepared Statements是由Cassandra解析的查询,然后保存供以后使用。 当驱动程序使用Prepared Statements时,它只需要发送要绑定的参数的值。 这会降低Cassandra内的网络流量和CPU利用率,因为Cassandra不必每次重新解析查询。使用Session.prepare()来准备查询:

user_lookup_stmt = session.prepare("SELECT * FROM users WHERE user_id=?")#准备语句使用'?'表示占位
users = []
for user_id in user_ids_to_query:
    user = session.execute(user_lookup_stmt, [user_id])
    users.append(user)

prepare()返回一个可用于替代SimpleStatement实例或字面字符串查询的PreparedStatement实例。 它将针对所有节点自动准备,并且必要时,驱动程序可以处理针对新节点和重新启动的节点的重新准备。
注意,准备语句的占位符是’?’字符, 这与简单的、非准备的语句不同(尽管驱动程序的未来版本可能使用相同的占位符)。

对Prepared Statements设置一致性等级

对Prepared Statements设置一致性等级,有两个方法:

  • 为每个执行的准备的语句设置默认的一致性等级:
    创建prepare语句对象->为对象设置一致性等级->在查询时绑定参数
from cassandra import ConsistencyLevel
cluster = Cluster()
session = cluster.connect("mykeyspace")
user_lookup_stmt = session.prepare("SELECT * FROM users WHERE user_id=?")#查询准备语句
user_lookup_stmt.consistency_level = ConsistencyLevel.QUORUM#prepare语句设置一致性等级
user1 = session.execute(user_lookup_stmt, [user_id1])[0]
user2 = session.execute(user_lookup_stmt, [user_id2])[0]
  • 从PreparedStatement和绑定的参数创建一个BoundStatement,并为之设置一致性等级:
    创建prepare语句对象->绑定参数创建新对象->新对象设置一致性等级->执行查询
user_lookup_stmt = session.prepare("SELECT * FROM users WHERE user_id=?")#查询准备语句
user3_lookup = user_lookup_stmt.bind([user_id3])#绑定参数
user3_lookup.consistency_level = ConsistencyLevel.ALL
user3 = session.execute(user3_lookup)

你可能感兴趣的:(database,python)