enum data type for liquibase - postgresql

I'm currently working on a liquibase.xml file to create table table_a. One of my fields is <column name="state" type="ENUM('yes','no')">
I'm using postgresql as my DBMS. is there anything like enum data type?
I've read in this like http://wiki.postgresql.org/wiki/Enum
that postgresql doesn't have such data type. CREATE TYPE function is used to create this data type. I still don't know how to make it in liquibase though.
Any suggestions?

Well of course PostgreSQL has an enum type (which is clearly documented in the link you have shown and the manual).
I don't think Liquibase "natively" supports enums for PostgreSQL, but you should be able to achieve it with a custom SQL:
<changeSet id="1" author="Arthur">
<sql>CREATE TYPE my_state AS ENUM ('yes','no')</sql>
<table name="foo">
<column name="state" type="my_state"/>
</table>
</changeSet>
For a simple yes/no column, I'd actually use the boolean type instead of an enum

An alternative to creating a new type would be a simple CHECK constraint on a varchar(3) column:
<changeSet id="1" author="X">
<table name="t">
<column name="c" type="varchar(3)"/>
</table>
<sql>ALTER TABLE t ADD CONSTRAINT check_yes_no CHECK (c = 'yes' OR c = 'no')</sql>
</changeSet>
That might play better with the client side, or not. I think boolean (as suggested by a_horse_with_no_name) would be a better call for this specific case: saying exactly what you mean usually works out better than the alternatives.

Related

Mybatis Generator Postgres return created id support

I'm using postgres for a project that I just started to work on, and I realized that Mybatis provide support to retrieve the autogenerated id keys for many databases but unfortunately postgres is not one of them, I modified a little bit the generated sql mappers and:
- changing select instead of insert in the generated xml
- add "RETURNING id" as last line of each sentence
so it gonna look like:
<select id="insert" keyColumn="id" keyProperty="id" parameterType="com.myproject.Order" ...
insert into ...
...
RETURNING id
</select>
with that change it works like a charm but the problem is that as soon as the generator is executed again the changes should be applied again manually, I was looking for a plugin to help me to automate the changes but I did not found any that seems to help, did you do any time before something similar? what would be the recommendation?
For the explanation, I created a table users in a schema mbtest.
create table mbtest.users (
id serial primary key,
name varchar(20)
);
The below is the <table /> element in the generator config.
(in the comment, I wrote sqlStatementType, but it should be sqlStatement)
<table tableName="users" domainObjectName="User"
schema="mbtest">
<generatedKey column="id" sqlStatement="JDBC" />
</table>
The generated 'UserMapper.xml' contains the following insert statement.
Note that useGeneratedKeys, keyColumn and keyProperty populated by the <generatedKey /> above.
<insert id="insert" keyColumn="id"
keyProperty="id" parameterType="test.model.User"
useGeneratedKeys="true">
<!--
WARNING - #mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sun Dec 08 12:36:30 JST 2019.
-->
insert into mbtest.users (name)
values (#{name,jdbcType=VARCHAR})
</insert>
(As the WARNING says, you should not modify the generated statements)
The insert statement will set the generated key to the id property of User.
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setName("User1");
mapper.insert(user);
sqlSession.commit();
assertNotNull(user.getId());
}
Here is a demo project so that you can verify yourself.

Force Liquibase to map Blob to BYTEA on PostgreSQL

How to tell Liquibase to map BLOB datatype to BYTEA on PostgreSQL?
It seems that Hibernate people has taken over and adapted the tool to their needs: https://liquibase.jira.com/browse/CORE-1863 , however, EclipseLink don't support oid's and the bug seems to be still open: https://bugs.eclipse.org/bugs/show_bug.cgi?id=337467
I need to use EclipseLink, and I need to use blobs with PostgreSQL. I'd like to use Liquibase, is it possible to make those things work together?
You have two options.
If you only need this for Postgres and don't plan to support other DBMS, simply use bytea as the column type.
Any data type that is not listed as one of the "generic" types in the description of the column tag will be passed "as-is" to the database, e.g.
<createTable tableName="foo">
<column name="id" type="integer"/>
<column name="picture" type="bytea"/>
</createTable>
If you want to support different DBMS, you can define a property depending on the DBMS:
<property name="blob_type" value="bytea" dbms="postgresql"/>
<property name="blob_type" value="blob" dbms="oracle"/>
then later
<createTable tableName="foo">
<column name="id" type="integer"/>
<column name="picture" type="${blob_type}"/>
</createTable>

Liquibase database autocomplete using Eclipse

Is there a way to get autocomplete for columns and tables from my database in a changelog file ?
<changeSet id="001" author="test">
<insert tableName="person">
<column name="id" valueComputed="seqPerson.NEXTVAL" />
<column name="myName" value="test" />
</insert>
<rollback>
DELETE FROM person WHERE myName='test';
</rollback>
</changeSet>
In this example I would like to have autocomplete for person, id, myName and seqPerson (and the Rollback tag...).
Note that I already have the LiquiBase tags autocompletion working from the xsd.
No, this is not currently possible. You might look at Datical DB - it has a changeset wizard that provides this sort of functionality.
Disclaimer - I work for Datical.

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.

Liquibase/PostgreSQL: how to preserve table case correctly?

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"