Liquibase/PostgreSQL: how to preserve table case correctly? - postgresql

I'm using Liquibase 3.1.1 to create tables in PostgreSQL 9.1. For example:
<changeSet id="1" author="bob">
<createTable tableName="BATCHES">
<!-- .. -- >
</createTable>
</changeSet>
However, the table gets created with a lowercase name:
# select * from "BATCHES";
ERROR: relation "BATCHES" does not exist
Is there any way to have Liquibase generate DDL that preserves the case of the table (and column etc) names that I specify in the change log?

You can use the objectQuotingStrategy="QUOTE_ALL_OBJECTS" attribute on your changeSet attribute or on the databaseChangeLog root element to override the default logic of "only quote objects that have to be"

Related

Alter index name using liquibase

I am trying to alter the index name using liquibase using the below code, but it is not working. The same sql statement is working directly in the db.
<changeSet author="sai" dbms="postgresql">
<preConditions onFail="MARK_RAN">
<indexExists indexName="employee_id_idx" schemaName="public"/>
</preConditions>
<sql>alter INDEX employee_id_idx RENAME TO department_id_idx</sql>
</changeSet>
Could anyone please let me know if there is any other way of doing alter to the index name using liquibase.
It works fine with the same code. But when we run the code if we have any error in the code, then it will be saved in DBChangeLog table, we need to remove that particular record and run again. This resolved the issue

liquibase + jdbctemplate update statement - autoincrement issue

In liquibase changset I am inserting some record to database
<changeSet id="test" author="xyz">
<insert tableName="testtable">
<column name="id" value="1"/>
<column name="name" value="testdata"/>
</insert>
</changeSet>
Then using jdbcTemplate I am trying to insert new rows using instance update() method.
jdbcTemplate.update(
"INSERT INTO test.testtable(name) VALUES (?)",
new Object[] {
someObject.getName()
});
When running above method for the first time, I am getting error that record with this ID already exists in the table. However when I repeat operation , I succeed with incremented ID with value 2.
How to integrate liquibase and jdbcTemplate together to eliminate this problem? I would expect that jdbcTemplate will somehow recognize that this ID 1 is already occupied and insert data with incremented, non-conflicting, unique ID.
I am using postgres.
Is there any option to do it without removing liquibase entry with hardcoded ID value?
I would expect that jdbcTemplate will somehow recognize that this ID
1 is already occupied and insert data with incremented,
non-conflicting, unique ID.
This would not happen. Liquibase looks to see if the changeset has been ran in the environment (by checking to see if the changeset id is present in the databasechangelog table). If it is not present, it will run the changeset. Just that simple, Liquibase is not doing any thinking for you, you have to make sure that the insert will work in any reasonable condition.
I did like the suggestion in the comment above to not insert an id but instead use an auto-increment if you are wanting to always insert and have the id increment.

How to enforce column order with Liquibase?

Setup:
liquibase 3.3.5
PostgreSQL 9.3
Windows 7 Ultimate
Having set the Liquibase.properties file with
changeLogFile = C://temp/changeset.xml,
I created a diff file with Liquibase (3.3.5).
liquibase.bat diffChangeLog
Examination of the changeset.xml file shows
-<addColumn tableName="view_dx">
<column type="int8" name="counter" defaultValueNumeric="0" defaultValue="0"/>
</addColumn
Problem is when
liquibase.bat update
is run, the changed table is NOT in the same column order as the reference table. This causes issues with the stored procedures using SETOF to return table rows.
Without destroying the existing table on the target database, how can column order be enforced using Liquibase?
TIA
I don't think that you can, in general, get Liquibase to enforce a column ordering. You will probably need to change your stored procedures to use column names rather than relying on position, which is a good habit to get into anyway.
Have you tried using afterColumn attribute of addColumn tag ?

How to rename a PostgreSQL table by prefixing an underscore?

I have a database which relies on a PostgreSQL system and I am maintaining it so I want to change tables and overall scheme. For this I thought of renaming the older tables so they have an underscore as a prefix. But this is not working:
DROP TABLE IF EXISTS _my_table; -- table does not exists, this does nothing
ALTER TABLE my_table
RENAME TO _my_table;
The result of the query is the following:
NOTICE: table "_my_table" does not exist, skipping ERROR:
type "_my_table" already exists
********** Error **********
ERROR: type "_my_table" already exists SQL state: 42710
The '_my_table' table is a fake name, but this error is reproduced by actually creating a '_my_table' table and running the same script above.
I am using pgAdmin III to access the database tables and making use of it's 'rename' operation results in the same error.
The postgresql documentation for the alter table method does not tell me explicitly about this particular problem: http://www.postgresql.org/docs/9.3/static/sql-altertable.html
Do I really need to use a prefix like 'backup' instead of '_' ? Or would it be possible to rename it, my only interest is to maintain the information in the table whilst having the minimal changes to the table name.
You cannot simply put an underscore in front of the existing table name because every table has an associated type that is... a leading underscore before the table name. You can verify this in the pg_catalog.pg_type table. Having a table name start with an underscore is not the problem, but the internal procedure is that a new table is created physically from the old table and only when the old table is no longer in use by other processes will the old table, and its associated type, be deleted. Hence the error referencing the type (and not the relation).
So if you really want to keep the old name with an underscore, you should first ALTER TABLE to some temp name and then ALTER TABLE to the underscore + original name. Or simply use another prefix...
ERROR: type "_my_table" already exists
Both tables and types are stored in the internal table pg_class. A unique name is required, that's why you get this error message.

liquibase:updateSQL does not create table schema prefix

I run liquibase:updateSQL with the following parameters on postgres:
changelogSchemaName online
defaultCatalogName online
defaultSchemaName online
It generates SQL like CREATE TABLE product but what I would expect is CREATE TABLE online.product
With the generated SQL the users search_path is used so I need to modify my DB before I can use liquibase:update
any Ideas how to fix that?
Have you used the catalogName attribute as described in the documentation?
For example:
<changeSet author="liquibase-docs" id="createTable-example">
<createTable catalogName="online" tableName="product"
<column name="x" type="varchar(255)"/>
<column name="y" type="varchar(255)"/>
</createTable>
</changeSet>
Use the outputDefaultCatalog=true or outputDefaultSchema=true maven parameters. That will force the generated SQL to include the default schema even if it is not specified in the changeSet.