hbase - 如何在不删除表的情况下更改表结构

Posted

技术标签:

【中文标题】hbase - 如何在不删除表的情况下更改表结构【英文标题】:hbase - how to change tables structure without drop tables 【发布时间】:2011-09-02 06:39:55 【问题描述】:

我使用 grails-1.3.2 和 gorm-hbase-0.2.4 插件。

有时我需要更改表结构(添加新表或列)。 我已经创建了 Car 表:

class Car
    static belongsTo = [user:User]

    String color
    String model
    //.....

    static constraints = 
    

但是当我想创建汽车对象时:

def create = 
        Car car = new Car()
        car.properties = params
        car.save(flush: true)        
 

我遇到了以下异常:

ERROR gorm.SavePersistentMethod  - APP_CAR
org.apache.hadoop.hbase.TableNotFoundException: APP_CAR

在我使用 create-drop 运行应用程序后,一切都开始运行良好.. 但我不能在每次更改后删除所有数据, 我认为插件必须完成所有更新

所以,在更改表结构继续运行应用程序而不删除表之后,我正在寻找某种方式..

如果有人知道解决方案,请帮忙。

【问题讨论】:

【参考方案1】:

Grails 不会自动更新您的表,如果它在生产环境中自动删除列怎么办?也许这不是你想要的。

有一个数据库迁移插件可以做到这一点,这里有一个很好的link 来解释它。请注意,您需要使用 grails prod 而不是直接使用链接中的那些,否则它将仅在开发模式下运行。该链接在其命令中未显示 prod。

官方链接是here,关于这个的spring源码博客是here。

【讨论】:

【参考方案2】:

数据库迁移插件将不起作用,因为它仅适用于休眠。 您需要对插件源进行一些更改。 HBasePluginSupport.grovy

static doWithApplicationContext = ApplicationContext applicationContext ->
    LOG.debug("Closure HBasePluginSupport.doWithApplicationContext invoked with arg $applicationContext")

    assert !PluginManagerHolder.getPluginManager().hasGrailsPlugin("hibernate"),"hibernate plug-in conflicts with gorm-hbase plug-in"

    // Read data source configuration, setting defaults as required
    def dataSource = application.config.dataSource
    // TODO write tests for this <--- Even maybe figure out if this is ever invoked
    if (!dataSource) dataSource = new HBaseDefaults()

    def dbCreate = dataSource?.dbCreate
    if (!dbCreate) dbCreate = "create-drop"
    LOG.debug("Data Source configured with dbCreate set to $dbCreate")

    // TODO Complete dbCreate related processing
    if (dbCreate?.toUpperCase()?.equals("CREATE-DROP")) 
        def createIndexedTables = dataSource?.indexed
        LOG.debug ("Flag createIndexedTables set to $createIndexedTables")
        def tableManager = HBaseLookupUtils.getBean("hbase.table.manager")

        tableManager.createSequenceTable()
        tableManager.createReferenceTable()

        application.domainClasses.each domainClass ->
            LOG.debug("Adding table for Domain Class $domainClass")
            tableManager.createDomainTable(domainClass, createIndexedTables)
        

        LOG.debug("List of all store found :")
        tableManager.getTableNames().each tn ->
            LOG.debug("- $tn")
        
     else if (dbCreate?.toUpperCase()?.equals("UPDATE")) 
        def createIndexedTables = dataSource?.indexed
        def tableManager = HBaseLookupUtils.getBean("hbase.table.manager")
        def existingTables = tableManager.getTableNames();

        application.domainClasses.each domainClass ->
            LOG.debug("Domain Class $domainClass")
            def tableDesc = new HTableDescriptor(HBaseNameUtils.getDomainTableName(domainClass))
            if (!existingTables.contains(tableDesc.getNameAsString())) 
                tableManager.createDomainTable(domainClass, createIndexedTables)
                LOG.debug("Adding table for Domain Class $domainClass")
            
        
    

    application.domainClasses.each domainClass ->
        LOG.debug("Adding dbms related methods to Domain Class $domainClass")
        def domainClassManager = new HBaseDomainClassManager()
        domainClassManager.createQueryMethods(domainClass)
        domainClassManager.createPersistenceMethods(domainClass)
        domainClassManager.addLazyLoadingSupport(domainClass)
        domainClassManager.addDynamicFinders(domainClass)
    

【讨论】:

以上是关于hbase - 如何在不删除表的情况下更改表结构的主要内容,如果未能解决你的问题,请参考以下文章

如何在不更改表架构的情况下将查询结果存储在当前表上?

如何在不重绘图表的情况下刷新 jqplot 条形图

如何在不删除数据库的情况下删除 phpMyAdmin 中数据库中所有表的内容?

psql - 如何在不删除表的情况下刷新数据库内容

oracle数据库表空间占用太大,如何在不删除表的情况下缩小占用空间

如何在不知道其表的情况下删除约束?