有没有一种简单的方法可以使用CQL (或API,如com.datastax.driver)来检查是否定义了Cassandra中的表(列族)?
目前,我倾向于执行SELECT 1 FROM table
并检查异常,但也许有更好的方法吗?
从1.1版本开始,您应该能够查询system
键空间中的schema_columnfamilies
列族。如果您知道要检查哪个键空间,此CQL应列出键空间中的所有列族:
截止到1.1版本,你应该可以查询system
keyspace,schema_columnfamilies
列族。如果你已经知道要查询的keyspace,以下CQL将列出该keyspace下所有的列族:
SELECT columnfamily_name
FROM schema_columnfamilies WHERE keyspace_name='myKeyspaceName';
这个功能的描述报告在此处:https://issues.apache.org/jira/browse/CASSANDRA-2477
但是请注意,系统列名称在1.1和1.2之间发生了一些变化。因此,您可能需要稍微调整一下才能获得所需的结果。
编辑20160523 - Cassandra 3.x更新:
请注意,对于Cassandra 3.0及以上版本,您需要对上述查询进行一些调整:
SELECT table_name
FROM system_schema.tables WHERE keyspace_name='myKeyspaceName';
Java驱动程序(因为你在问题中提到了它)也维护着模式的本地表示。
3.x及以下版本的驱动程序:
KeyspaceMetadata ks = cluster.getMetadata().getKeyspace("myKeyspace");
TableMetadata table = ks.getTable("myTable");
boolean tableExists = (table != null);
驱动程序 4.x 及以上版本:
Metadata metadata = session.getMetadata();
boolean tableExists =
metadata.getKeyspace("myKeyspace")
.flatMap(ks -> ks.getTable("myTable"))
.isPresent();
TableMetadata
来做到这一点。 - Aaron.get()
来解开Optional<KeyspaceMetadata>
,但除此之外它仍然可以工作。 - lapo我只需要使用cqlsh手动检查表的存在性。以下是一些可能有用的一般信息。
describe keyspace_name.table_name
CassandraCSharpDriver
版本3.17.1,以下代码将在表不存在时创建它:var ks = _cassandraSession.Cluster.Metadata.GetKeyspace(keyspaceName);
var tableNames = ks.GetTablesNames();
if(!tableNames.Contains(tableName.ToLowerInvariant()))
{
var stmt = new SimpleStatement($"CREATE TABLE {tableName} (id text PRIMARY KEY, name text, price decimal, volume int, time timestamp)");
_cassandraSession.Execute(stmt);
}
您需要根据自己的需求调整表列列表。这也可以在异步方法中使用await _cassandraSession.ExecuteAsync(stmt).ConfigureAwait(false)
来等待。
另外,我想提一下,我正在使用Cassandra 4.0.1版本。
SELECT * FROM system_schema.tables WHERE table_name='testmap' ALLOW FILTERING;
因为system_schema
键空间使用了LocalStrategy
,所以与在常规表上使用ALLOW FILTERING
相比,它不会那么低效。 - Aaron