Skip to content

Commit

Permalink
Merge branch 'master' of github.com:pycassa/pycassa
Browse files Browse the repository at this point in the history
Conflicts:
	README.mkd
  • Loading branch information
thobbs committed Nov 12, 2011
2 parents fb67a2d + ec9a5de commit d880db7
Show file tree
Hide file tree
Showing 49 changed files with 3,964 additions and 2,537 deletions.
11 changes: 11 additions & 0 deletions AUTHORS
Expand Up @@ -12,3 +12,14 @@ Carlo Pires
Bjorn Edstrom
Adam Lowry
Wojciech 'KosciaK' Pietrzok
Joaquin Casares
Savino Sguera
Dan Kuebrich
Paul Cannon
Kay Sackey
Alexey Smolsky
Samuel Sutch
Aaron Morton
Ian Danforth
John Calixto
Justin Plock
104 changes: 104 additions & 0 deletions CHANGES
@@ -1,3 +1,107 @@
Changes in Version 1.3.0

This release adds full compatibility with Cassandra 1.0 and removes support
for schema manipulation in Cassandra 0.7.

In this release, schema manipulation should work with Cassandra 0.8 and 1.0,
but not 0.7. The data API should continue to work with all three versions.

Bug Fixes

* Don’t ignore columns parameter in ColumnFamilyMap.insert()
* Handle empty instance fields in ColumnFamilyMap.insert()
* Use the same default for timeout in pycassa.connect() as ConnectionPool
uses
* Fix typo which caused a different exception to be thrown when an
AllServersUnavailable exception was raised
* IPython 0.11 compatibility in pycassaShell
* Correct dependency declaration in setup.py
* Add UUIDType to supported types

Features

The filter_empty parameter was added to get_range() with a default of True;
this allows empty rows to be kept if desired

Deprecated

pycassa.connect()
pycassa.connect_thread_local()


Changes in Version 1.2.1

This is strictly a bug-fix release addressing a few issues created in 1.2.0.

Bug Fixes

* Correctly check for Counters in ColumnFamily when setting
default_validation_class
* Pass kwargs in ColumnFamilyMap to ColumnFamily
* Avoid potential UnboundLocal in ConnectionPool.execute() when get() fails
* Fix ez_setup dependency/bundling so that package installations using
easy_install or pip don’t fail without ez_setup installed


Changes in Version 1.2.0

This should be a fairly smooth upgrade from pycassa 1.1. The
primary changes that may introduce minor incompatibilities are
the changes to ColumnFamilyMap and the automatic skipping of
"ghost ranges" in .ColumnFamily.get_range().

Features

* Add ConnectionPool.fill()
* Add FloatType, DoubleType, DateType, and BooleanType support.
* Add CompositeType support for static composites. See "Composite Types"
for more details.
* Add timestamp, ttl to ColumnFamilyMap.insert() params
* Support variable-length integers with IntegerType. This allows more
space-efficient small integers as well as integers that exceed the size
of a long.
* Make ColumnFamilyMap a subclass of ColumnFamily instead of using one
as a component. This allows all of the normal adjustments normally done
to a ColumnFamily to be done to a ColumnFamilyMap instead. See "Class
Mapping with Column Family Map" for examples of using the new version.
* Expose the following ConnectionPool attributes, allowing them to be
altered after creation: max_overflow, pool_timeout, recycle,
max_retries, and logging_name. Previously, these were all supplied as
constructor arguments. Now, the preferred way to set them is to alter
the attributes after creation. (However, they may still be set in the
constructor by using keyword arguments.)
* Automatically skip "ghost ranges" in ColumnFamily.get_range().
Rows without any columns will not be returned by the generator,
and these rows will not count towards the supplied row_count.

Bug Fixes

* Add connections to ConnectionPool more readily when prefill is False.
Before this change, if the ConnectionPool was created with prefill=False,
connections would only be added to the pool when there was concurrent
demand for connections. After this change, if prefill=False and
pool_size=N, the first N operations will each result in a new connection
being added to the pool.
* Close connection and adjust the ConnectionPool‘s connection count after a
TApplicationException. This exception generally indicates programmer error,
so it’s not extremely common.
* Handle typed keys that evaluate to False

Deprecated

* ConnectionPool.recreate()
* ConnectionPool.status()

Miscellaneous

* Better failure messages for ConnectionPool failures
* More efficient packing and unpacking
* More efficient multi-column inserts in ColumnFamily.insert() and
ColumnFamily.batch_insert()
* Prefer Python 2.7’s collections.OrderedDict over the bundled version when
available


Changes in Version 1.1.1

Features
Expand Down
98 changes: 53 additions & 45 deletions README.mkd
Expand Up @@ -10,7 +10,8 @@ with the following features:
* A batch interface
* A class for mapping classes to Cassandra column families

The latest release is compatible with Cassandra 0.7 and 0.8.
The latest release is fully compatible with Cassandra 0.8 and 1.0, and
compatible with the data API of 0.7.

*pycassa* is open source under the [MIT license](http://www.opensource.org/licenses/mit-license.php).

Expand All @@ -31,7 +32,7 @@ Getting Help

IRC:

* Use channel #cassandra on irc.freenode.net. If you don't have an IRC client,
* Use the #cassandra channel on irc.freenode.net. If you don't have an IRC client,
you can use [freenode's web based client](http://webchat.freenode.net/?channels=#cassandra).

Mailing List:
Expand All @@ -42,15 +43,15 @@ Mailing List:
Installation
------------

If easy_install is available, you can use:
If pip is available, you can install the lastest pycassa release
with:

easy_install pycassa
pip install pycassa

The simplest way to install manually is to copy the pycassa directories to
your program. If you want to install, make sure you have thrift installed,
and run setup.py as a superuser.
If you want to install from a source checkout, make sure you have Thrift
installed, and run setup.py as a superuser:

easy_install thrift
pip install thrift
python setup.py install

Basic Usage
Expand All @@ -61,52 +62,59 @@ To get a connection pool, pass a Keyspace and an optional list of servers:
~~~~~~ {python}
>>> import pycassa
>>> pool = pycassa.ConnectionPool('Keyspace1') # Defaults to connecting to the server at 'localhost:9160'
>>>
>>> # or, we can specify our servers:
>>> pool = pycassa.ConnectionPool('Keyspace1', server_list=['192.168.2.10'])
~~~~~~

To use the standard interface, create a ColumnFamily instance.

>>> pool = pycassa.ConnectionPool('Keyspace1')
>>> cf = pycassa.ColumnFamily(pool, 'Standard1')
>>> cf.insert('foo', {'column1': 'val1'})
1261349837816957
>>> cf.get('foo')
{'column1': 'val1'}
~~~~~~ {python}
>>> pool = pycassa.ConnectionPool('Keyspace1')
>>> cf = pycassa.ColumnFamily(pool, 'Standard1')
>>> cf.insert('foo', {'column1': 'val1'})
>>> cf.get('foo')
{'column1': 'val1'}
~~~~~~

insert() also acts to update values:
insert() will also update existing columns:

>>> cf.insert('foo', {'column1': 'val2'})
1261349910511572
>>> cf.get('foo')
{'column1': 'val2'}
~~~~~~ {python}
>>> cf.insert('foo', {'column1': 'val2'})
>>> cf.get('foo')
{'column1': 'val2'}
~~~~~~

You may insert multiple columns at once:

>>> cf.insert('bar', {'column1': 'val3', 'column2': 'val4'})
1261350013606860
>>> cf.multiget(['foo', 'bar'])
{'foo': {'column1': 'val2'}, 'bar': {'column1': 'val3', 'column2': 'val4'}}
>>> cf.get_count('bar')
2

get_range() returns an iterable. Call it with list() to convert it to a list.

>>> list(cf.get_range())
[('bar', {'column1': 'val3', 'column2': 'val4'}), ('foo', {'column1': 'val2'})]
>>> list(cf.get_range(row_count=1))
[('bar', {'column1': 'val3', 'column2': 'val4'})]

You can remove entire keys or just a certain column.

>>> cf.remove('bar', columns=['column1'])
1261350220106863
>>> cf.get('bar')
{'column2': 'val4'}
>>> cf.remove('bar')
1261350226926859
>>> cf.get('bar')
Traceback (most recent call last):
...
cassandra.ttypes.NotFoundException: NotFoundException()
~~~~~~ {python}
>>> cf.insert('bar', {'column1': 'val3', 'column2': 'val4'})
>>> cf.multiget(['foo', 'bar'])
{'foo': {'column1': 'val2'}, 'bar': {'column1': 'val3', 'column2': 'val4'}}
>>> cf.get_count('bar')
2
~~~~~~

get_range() returns an iterable. You can use list() to convert it to a list:

~~~~~~ {python}
>>> list(cf.get_range())
[('bar', {'column1': 'val3', 'column2': 'val4'}), ('foo', {'column1': 'val2'})]
>>> list(cf.get_range(row_count=1))
[('bar', {'column1': 'val3', 'column2': 'val4'})]
~~~~~~

You can remove entire keys or just a certain column:

~~~~~~ {python}
>>> cf.remove('bar', columns=['column1'])
>>> cf.get('bar')
{'column2': 'val4'}
>>> cf.remove('bar')
>>> cf.get('bar')
Traceback (most recent call last):
...
pycassa.NotFoundException: NotFoundException()
~~~~~~

See the [tutorial](http://pycassa.github.com/pycassa/tutorial.html#connecting-to-cassandra) for more details.
Binary file added doc/_static/favicon.ico
Binary file not shown.
8 changes: 0 additions & 8 deletions doc/api/index.rst
Expand Up @@ -17,11 +17,3 @@ Pycassa Modules
pycassa/util
pycassa/connection
pycassa/logging/pycassa_logger

Thrift Generated Modules
------------------------

.. toctree::
:maxdepth: 3

pycassa/cassandra/ttypes
5 changes: 0 additions & 5 deletions doc/api/pycassa/cassandra/ttypes.rst

This file was deleted.

4 changes: 3 additions & 1 deletion doc/api/pycassa/pool.rst
Expand Up @@ -17,7 +17,9 @@

.. automethod:: get

.. automethod:: return_conn
.. automethod:: put

.. automethod:: execute

.. automethod:: fill

Expand Down
81 changes: 81 additions & 0 deletions doc/assorted/column_family_map.rst
@@ -0,0 +1,81 @@
.. _column-family-map:

Class Mapping with Column Family Map
====================================
You can map existing classes to column families using
:class:`~pycassa.columnfamilymap.ColumnFamilyMap`.

To specify the fields to be persisted, use any of the
subclasses of :class:`pycassa.types.CassandraType` available
in :mod:`pycassa.types`.

.. code-block:: python
>>> from pycassa.types import *
>>> class User(object):
... key = LexicalUUIDType()
... name = Utf8Type()
... age = IntegerType()
... height = FloatType()
... score = DoubleType(default=0.0)
... joined = DateType()
The defaults will be filled in whenever you retrieve instances from the
Cassandra server and the column doesn't exist. If you want to add a
column in the future, you can simply add the relevant attribute to the class
and the default value will be used when you get old instances.

.. code-block:: python
>>> from pycassa.pool import ConnectionPool
>>> from pycassa.columnfamilymap import ColumnFamilyMap
>>>
>>> pool = ConnectionPool('Keyspace1')
>>> cfmap = ColumnFamilyMap(pool, User, 'users')
All the functions are exactly the same as for :class:`ColumnFamily`,
except that they return instances of the supplied class when possible.

.. code-block:: python
>>> from datetime import datetime
>>> import uuid
>>>
>>> key = uuid.uuid4()
>>>
>>> user = User()
>>> user.key = key
>>> user.name = 'John'
>>> user.age = 18
>>> user.height = 5.9
>>> user.joined = datetime.now()
>>> cfmap.insert(user)
1261395560186855
.. code-block:: python
>>> user = cfmap.get(key)
>>> user.name
"John"
>>> user.age
18
.. code-block:: python
>>> users = cfmap.multiget([key1, key2])
>>> print users[0].name
"John"
>>> for user in cfmap.get_range():
... print user.name
"John"
"Bob"
"Alex"
.. code-block:: python
>>> cfmap.remove(user)
1261395603906864
>>> cfmap.get(user.key)
Traceback (most recent call last):
...
cassandra.ttypes.NotFoundException: NotFoundException()

0 comments on commit d880db7

Please sign in to comment.