Scylla Documentation Logo Documentation
  • Server
    • Scylla Open Source
    • Scylla Enterprise
    • Scylla Alternator
  • Cloud
    • Scylla Cloud
    • Scylla Cloud Docs
  • Tools
    • Scylla Manager
    • Scylla Monitoring Stack
    • Scylla Operator
  • Drivers
    • CQL Drivers
    • DynamoDB Drivers
Download
Menu

Caution

You're viewing documentation for a previous version of Scylla Python Driver. Switch to the latest stable version.

Scylla Python Driver User Defined Types

User Defined Types¶

Cassandra 2.1 introduced user-defined types (UDTs). You can create a new type through CREATE TYPE statements in CQL:

CREATE TYPE address (street text, zip int);

Version 2.1 of the Python driver adds support for user-defined types.

Registering a UDT¶

You can tell the Python driver to return columns of a specific UDT as instances of a class or a dict by registering them with your Cluster instance through Cluster.register_user_type():

Map a Class to a UDT¶

cluster = Cluster(protocol_version=3)
session = cluster.connect()
session.set_keyspace('mykeyspace')
session.execute("CREATE TYPE address (street text, zipcode int)")
session.execute("CREATE TABLE users (id int PRIMARY KEY, location frozen<address>)")

# create a class to map to the "address" UDT
class Address(object):

    def __init__(self, street, zipcode):
        self.street = street
        self.zipcode = zipcode

cluster.register_user_type('mykeyspace', 'address', Address)

# insert a row using an instance of Address
session.execute("INSERT INTO users (id, location) VALUES (%s, %s)",
                (0, Address("123 Main St.", 78723)))

# results will include Address instances
results = session.execute("SELECT * FROM users")
row = results[0]
print(row.id, row.location.street, row.location.zipcode)

Map a dict to a UDT¶

cluster = Cluster(protocol_version=3)
session = cluster.connect()
session.set_keyspace('mykeyspace')
session.execute("CREATE TYPE address (street text, zipcode int)")
session.execute("CREATE TABLE users (id int PRIMARY KEY, location frozen<address>)")

cluster.register_user_type('mykeyspace', 'address', dict)

# insert a row using a prepared statement and a tuple
insert_statement = session.prepare("INSERT INTO mykeyspace.users (id, location) VALUES (?, ?)")
session.execute(insert_statement, [0, ("123 Main St.", 78723)])

# results will include dict instances
results = session.execute("SELECT * FROM users")
row = results[0]
print(row.id, row.location['street'], row.location['zipcode'])

Using UDTs Without Registering Them¶

Although it is recommended to register your types with Cluster.register_user_type(), the driver gives you some options for working with unregistered UDTS.

When you use prepared statements, the driver knows what data types to expect for each placeholder. This allows you to pass any object you want for a UDT, as long as it has attributes that match the field names for the UDT:

cluster = Cluster(protocol_version=3)
session = cluster.connect()
session.set_keyspace('mykeyspace')
session.execute("CREATE TYPE address (street text, zipcode int)")
session.execute("CREATE TABLE users (id int PRIMARY KEY, location frozen<address>)")

class Foo(object):

    def __init__(self, street, zipcode, otherstuff):
        self.street = street
        self.zipcode = zipcode
        self.otherstuff = otherstuff

insert_statement = session.prepare("INSERT INTO users (id, location) VALUES (?, ?)")

# since we're using a prepared statement, we don't *have* to register
# a class to map to the UDT to insert data.  The object just needs to have
# "street" and "zipcode" attributes (which Foo does):
session.execute(insert_statement, [0, Foo("123 Main St.", 78723, "some other stuff")])

# when we query data, UDT columns that don't have a class registered
# will be returned as namedtuples:
results = session.execute("SELECT * FROM users")
first_row = results[0]
address = first_row.location
print(address)  # prints "Address(street='123 Main St.', zipcode=78723)"
street = address.street
zipcode = address.street

As shown in the code example, inserting data for UDT columns without registering a class works fine for prepared statements. However, you must register a class to insert UDT columns with unprepared statements.* You can still query UDT columns without registered classes using unprepared statements, they will simply return namedtuple instances (just like prepared statements do).

* this applies to parameterized unprepared statements, in which the driver will be formatting parameters – not statements with interpolated UDT literals.

PREVIOUS
Security
NEXT
Object Mapper
  • 3.24.8
    • 3.25.4
    • 3.24.8
    • 3.22.3
    • 3.21.0
  • API Documentation
    • cassandra - Exceptions and Enums
    • cassandra.cluster - Clusters and Sessions
    • cassandra.policies - Load balancing and Failure Handling Policies
    • cassandra.auth - Authentication
    • cassandra.graph - Graph Statements, Options, and Row Factories
    • cassandra.metadata - Schema and Ring Topology
    • cassandra.metrics - Performance Metrics
    • cassandra.query - Prepared Statements, Batch Statements, Tracing, and Row Factories
    • cassandra.pool - Hosts and Connection Pools
    • cassandra.protocol - Protocol Features
    • cassandra.encoder - Encoders for non-prepared Statements
    • cassandra.decoder - Data Return Formats
    • cassandra.concurrent - Utilities for Concurrent Statement Execution
    • cassandra.connection - Low Level Connection Info
    • cassandra.util - Utilities
    • cassandra.timestamps - Timestamp Generation
    • cassandra.io.asyncioreactor - asyncio Event Loop
    • cassandra.io.asyncorereactor - asyncore Event Loop
    • cassandra.io.eventletreactor - eventlet-compatible Connection
    • cassandra.io.libevreactor - libev Event Loop
    • cassandra.io.geventreactor - gevent-compatible Event Loop
    • cassandra.io.twistedreactor - Twisted Event Loop
    • cassandra.cqlengine.models - Table models for object mapping
    • cassandra.cqlengine.columns - Column types for object mapping models
    • cassandra.cqlengine.query - Query and filter model objects
    • cassandra.cqlengine.connection - Connection management for cqlengine
    • cassandra.cqlengine.management - Schema management for cqlengine
    • cassandra.cqlengine.usertype - Model classes for User Defined Types
    • cassandra.datastax.graph - Graph Statements, Options, and Row Factories
    • cassandra.datastax.graph.fluent
    • cassandra.datastax.graph.fluent.query
    • cassandra.datastax.graph.fluent.predicates
  • Installation
  • Getting Started
  • Scylla Specific Features
  • Upgrading
  • Execution Profiles
  • Performance Notes
  • Paging Large Queries
  • Lightweight Transactions (Compare-and-set)
  • Security
  • User Defined Types
  • Object Mapper
    • Upgrade Guide
    • Models
    • Making Queries
    • Batch Queries
    • Connections
    • Third party integrations
    • Frequently Asked Questions
  • Working with Dates and Times
  • Scylla Cloud
  • Frequently Asked Questions
  • Create an issue
  • Edit this page

On this page

  • User Defined Types
    • Registering a UDT
      • Map a Class to a UDT
      • Map a dict to a UDT
    • Using UDTs Without Registering Them
Logo
Docs Contact Us About Us
Mail List Icon Slack Icon
© ScyllaDB 2021 and © DataStax 2013-2017
Powered by Sphinx 4.3.2 & ScyllaDB Theme 1.2.2