How to add indexes to already created table in Liquibase - postgresql

There is already created table 'A'
'id' 'b_id' 'name'
1 2 someName
Now I want to add unique index to id and b_id columns
How to do it in yml format

based on documentation, something like this:
changeSet:
id: addUniqueConstraint-example
author: liquibase-docs
changes:
- addUniqueConstraint:
catalogName: cat
clustered: false
columnNames: id, b_id
constraintName: const_name
deferrable: true
disabled: false
forIndexName:
initiallyDeferred: true
schemaName: [yourschema]
tableName: [yourtablename]
tablespace:
validate: true

Related

SQLC Override Bool Type PostgreSQL

I am using SQLC and my YAML config file contains the following type overrides for postgresql:
gen:
go:
emit_json_tags: true
package: "hmdb"
out: "hmdb"
overrides:
- db_type: "hstore"
nullable: true
go_type: "github.com/jackc/pgtype.Hstore"
- db_type: "text"
nullable: true
go_type:
import: "gopkg.in/guregu/null.v4"
package: "null"
type: "String"
- db_type: "timestamptz"
nullable: true
go_type:
import: "gopkg.in/guregu/null.v4"
package: "null"
type: "Time"
Everything here works, but if I add:
- db_type: "bool"
nullable: true
go_type:
import: "gopkg.in/guregu/null.v4"
package: "null"
type: "Bool"
I do not get the expected result. I have also tried boolean and bit to no avail, both with and without nullable.
I have an update query defined here:
-- name: SetUser :one
UPDATE users SET
username = coalesce(sqlc.narg(username), username),
email = coalesce(sqlc.narg('email'), email),
phone = coalesce(sqlc.narg('phone'), phone),
password = coalesce(sqlc.narg('password'), password),
mfatoken = coalesce(sqlc.narg('mfatoken'), mfatoken),
active = coalesce(sqlc.narg('active'), active)
WHERE id = $1 RETURNING *;
But the generated struct looks like:
type SetUserParams struct {
ID uuid.UUID `json:"id"`
Username null.String `json:"username"`
Email null.String `json:"email"`
Phone null.String `json:"phone"`
Password null.String `json:"password"`
MFAToken null.String `json:"mfatoken"`
Active sql.NullBool `json:"active"`
}
I want to use null.Bool instead of sql.NullBool, is this possible?
Create your schema.yaml like this:
CREATE TABLE users (
...
active pg_catalog.bool
)
In sqlc.yaml the entry should look something like this:
- db_type: "pg_catalog.bool"
nullable: true
go_type:
import: "gopkg.in/guregu/null.v4"
package: "null"
type: "Bool"
Then after sqlc generate it would look like this:
type SetUserParams struct {
...
Active null.Bool `json:"active"`
}
So it uses null.Bool instead of sql.NullBool.

Does the EFCore migration locks entire schema?

In our project, we handle DB (Postgres) migrations using EFCore migrations (but we write them ourselves, they are not autogenerated). Example script:
// it is making column nullable
migrationBuilder.AlterColumn<string>(
name: "discount_type",
table: some_table_name,
nullable: true,
schema: "some_schema");
// it is making column nullable
migrationBuilder.AlterColumn<decimal>(
name: "discount_value",
table: some_table_name,
nullable: true,
schema: "some_schema");
migrationBuilder.AddForeignKey(
name: "some_key_name_fk",
table: some_table_name,
column: "code_id",
schema: "some_schema",
principalTable: some_table_name_2,
principalColumn: "id",
principalSchema: "some_schema",
onDelete: ReferentialAction.Restrict);
migrationBuilder.DropColumn(
name: "description_english",
table: some_table_name,
schema: Constants.Schema);
migrationBuilder.DropColumn(
name: "description_german",
table: some_table_name,
schema: "some_schema");
We found that during the migration, our service become unresponsive for few minutes. All queries (SELECT queries in majority) where giving timeout. 100% requests failed. Please note that some_table_name table has over 120 million records.
My question is if EFCore migration somehow locks the entire DB schema, even preventing it from reading data? If 'yes' - how to prevent it?

Setting up spring boot project with liquibase

I have a spring boot 2 project(jhipster) and I am a little confused on how hibernate tables work with liquibase.
Right now I have a bunch of data classes with hibernate annotations and I would like to insert some static data for testing purposes. I have a bunch of questions in getting started.
Do I have to define liquibase changeSets to create tables when I already have the hibernate annotated data classes?
How do I run liquibase changeSets when configuring the database?
EDIT -----
How are the foreign key relationships named between the changeset and the domain(java) code? For example I have a Person table and it holds a reference to an Address table. How do I represent this relationship within the changeSet table?
The Person table doesn't hold an id of an Address, it holds the reference.
Spring boot has excellent integration with liquibase.
If you want liquibase to handle creation of the tables (DDL) and not hibernate:
you need to disable the hibernate auto-create flag.
set spring.jpa.hibernate.ddl-auto=none
(or) remove this property from application.yml file.
Just include following into pom.xml:
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
Below is the sample code to create tables and insert data into table.
File location:
src/main/resources/db/changelog/db.changelog-master.yaml
databaseChangeLog:
- changeSet:
id: 1
author: sgollapinni
changes:
- createTable:
tableName: person
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: first_name
type: varchar(255)
constraints:
nullable: false
- column:
name: last_name
type: varchar(255)
constraints:
nullable: false
- createTable:
tableName: address
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: city
type: varchar(255)
constraints:
nullable: false
- column:
name: person_id
type: varchar(255)
constraints:
nullable: false
foreignKeyName: fk_person_address
references: person(id)
- changeSet:
id: 2
author: sgollapinni
changes:
- insert:
tableName: person
columns:
- column:
name: first_name
value: Sunil
- column:
name: last_name
value: Kumar
- insert:
tableName: address
columns:
- column:
name: city
value: Bangalore
- column:
name: user_id
value: (Select id from person where name = 'Sunil')
Otherwise, if you want hibernate to handle the DDL and only you want to insert some static data for testing purposes, you can still do this using liquibase.
You can use changeSets to add the DML statements.
- changeSet:
id: 1
author: sgollapinni
changes:
- insert:
tableName: person
columns:
- column:
name: first_name
value: Sunil
- column:
name: last_name
value: Kumar
- insert:
tableName: address
columns:
- column:
name: city
value: Bangalore
- column:
name: user_id
value: (Select id from person where name = 'Sunil')
Hope it helps!

rails PG undefined column does not exist for index creation

I'm trying to add an index for a for column but I'm getting the error:
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column "contact" does not exist
: CREATE UNIQUE INDEX "index_users_on_contact" ON "users" ("contact")
which is strange because as you an see I'm creating the column before I try to index it:
class AddContactToUser < ActiveRecord::Migration[5.1]
def change
add_reference :users, :contact, foreign_key: true
add_index :users, :contact, unique: true
end
end
Why am I getting this error?
In case your wondering why I'm doing a separate contact model, it's because all users will have a contact but not all contacts will have a user.
add_reference :users, :contact, foreign_key: true
Creates a column named contact_id. So you're index needs to be
add_index :users, :contact_id, unique: true

What's the proper way to add an index to a table in a Rails migration?

I'm using Rails 5 with PostGres 9.5 . I have the following migration
class CreateCryptoIndexCurrencies < ActiveRecord::Migration[5.0]
def change
create_table :crypto_index_currencies do |t|
t.references :crypto_currency, foreign_key: true
t.date :join_date, :null => false, :default => Time.now
t.timestamps
end
add_index :crypto_index_currencies, :crypto_currency, unique: true
end
end
Upon running the migration, it is dying with this error
PG::UndefinedColumn: ERROR: column "crypto_currency" does not exist
What is the proper way to add the index? The table name that I want to reference is called "crypto_currencies".
add_index 'crypto_index_currencies', ['crypto_currency'], name: "index_crypto_index_currencies_on_crypto_currency", unique: true, using: :btree
using: :btree its optional.
This is the syntax to add it inside the create_table block
class CreateCryptoIndexCurrencies < ActiveRecord::Migration[5.0]
def change
create_table :crypto_index_currencies do |t|
t.references :crypto_currency, foreign_key: true
t.date :join_date, :null => false, :default => Time.now
t.index :crypto_currency, unique: true
end
end
end