I have a ENUM column and I am using liquibase addCheckConstraint to allow only ENUM values. However, addCheckConstraint doesnt work and allows any value. My yaml changelog looks as follows:
- changeSet:
id: 1565352995028-1
author: Zafrullah Syed
changes:
- createTable:
columns:
- column:
constraints:
primaryKey: true
name: ID
type: NUMBER(19, 0)
- column:
name: STATUS_ENUM
type: VARCHAR2(10 CHAR)
tableName: BOOKING
- addCheckConstraint:
constraintBody: STATUS_ENUM IN ('ERROR', 'CONFIRMED', 'QUEUED', 'REJECTED')
constraintName: enumcheck
tableName: SOME_TABLE
I am Using Oracle db.
If I try to run a sql query, then constraint works well:
ALTER TABLE SOME_TABLE
ADD CONSTRAINT enumcheck CHECK (status_enum IN ('ERROR', 'CONFIRMED', 'QUEUED', 'REJECTED'));
I tried to add another enableCheckConstraint to enable the existing check constraint but nothing seems to work.
addCheckConstraint is accessible only for the pro version, do you have it?
Related
databaseChangeLog:
- preConditions:
- changeSet:
id: 8
author: myname
context: context
changes:
- createIndex:
tableName: table_name
indexname: index_name
columns:
- column:
name: column_1
Get an error:
DatabaseException: ORA-00953: missing or invalid index name
[Failed SQL: CREATE INDEX ON SYSTEM.CABLEMODEMTERMINATIONSYSTEM(KMA_ID)]
The problem is indexname, it should be indexName (upper-case N).
I've been struggling for some time now to figure out a way to create a composite foreign key in liquibase.
I have a table A which has a composite PK, let's say (id1, id2). I'm trying to make another table B, in which the A.PK is mapped as a FK.
I'm using liquibase with YAML and something doesn't seem to add up.
I've tried adding the FK when creating the table (so in the column tag)
- column:
name: id1_id2
type: int
constraints:
nullable: false
foreignKeyName: fk_id1_id2
references: A(id1, id2)
Unfortunately this syntax returns an error:
Caused by: java.sql.SQLSyntaxErrorException: ORA-02256: number of referencing columns must match referenced columns
Another thing that I've tried is creating the table first, with the column for the desired FK and try to add a FK constraint on that column. This doesn't throw any error but it does nothing (also the log for LB says "empty" in the description)
changes:
- addForeignKeyContraint:
baseColumnNames: id1, id2
baseTableName: B
constraintName: fb_id1_id2
referencedColumnNames: id1, id2
referencedTableName: A
Any help would be much appreciated.
Thanks
Have you tried addForeignKeyConstraint? Something like this:
- changeSet:
id: 1
author: you
changes:
- addForeignKeyConstraint:
baseColumnNames: id1, id2
baseTableName: tableB
constraintName: FK_tableB_tableA
referencedColumnNames: id1, id2
referencedTableName: tableA
I don't use Liquibase, but here's how it is supposed to look like, as far as Oracle is concerned: if you want to create a composite foreign key (in the detail table), then it has to reference a composite primary key (in the master table).
Have a look at this example:
SQL> create table master
2 (id_1 number,
3 id_2 number,
4 constraint pk_mas primary key (id_1, id_2));
Table created.
SQL> create table detail
2 (id_det number constraint pk_det primary key,
3 --
4 id_1 number,
5 id_2 number,
6 constraint fk_det_mas foreign key (id_1, id_2) references master (id_1, id_2));
Table created.
SQL>
It just wouldn't work otherwise; that's why you got the error
ORA-02256: number of referencing columns must match referenced columns
because your detail table contained a single column (id1_id2) and tried to reference two columns in table A (id1, id2).
How can I create a table with a composite primary key with this library. For example:
CREATE TABLE something (
column1,
column2,
column3,
PRIMARY KEY (column1, column2)
);
The only example I see in the documentation is a primary key on single column:
try db.run(users.create { t in
t.column(id, primaryKey: true)
t.column(email, unique: true)
t.column(name)
})
I tried the following but fails with an error (...table "" has more than one primary key) :
try db.run(tblTsMosStaged.create { t in
t.column(colTsMosStagedEventId, primaryKey: true)
t.column(colTsMosStagedEventInstance, primaryKey: true)
t.column(colTsMosStagedTaxId, primaryKey: true)
t.column(colTsMosStagedRankId)
...
Or is this only possible via Executing Arbitrary SQL
The SQLite.swift documentation says:
Table Constraints
Additional constraints may be provided outside the scope of a single column using the following functions.
primaryKey adds a PRIMARY KEY constraint to the table. Unlike the column constraint, above, it supports all SQLite types, ascending and descending orders, and composite (multiple column) keys.
t.primaryKey(email.asc, name)
// PRIMARY KEY("email" ASC, "name")
try db.run(tblTsMosStaged.create { t in
t.column(colTsMosStagedEventId)
t.column(colTsMosStagedEventInstance)
t.column(colTsMosStagedTaxId)
t.column(colTsMosStagedRankId)
//ADD this line
t.primaryKey(colTsMosStagedEventId, colTsMosStagedEventInstance, colTsMosStagedTaxId)
I have a table in a SQLite database created with the code below. Note the compound primary key:
db.create_table(:person_hash) do
Integer :person_id
Bignum :hash // MD5 hash in hex stored as numeric: hash.to_i(16)
primary_key [:person_id, :hash]
end
This table has some rows already:
puts db[:person_hash].where(:person_id => 285577).all
# {:person_id=>285577, :hash=>306607097659338192312932577746542919680}
Now, when I try to insert this:
db[:person_hash].insert({:person_id=>285577, :hash=>306607097659338206333361532286405644297})
I get this:
SQLite3::ConstraintException: columns person_id, hash are not unique (Sequel::DatabaseError)
If the row does not already exist in the table, how can it be a duplicate?
I tried inserting another hash for the same person ID instead, and it worked without problems.
This appears to be a bug in SQLite:
$ sqlite3
SQLite version 3.8.9 OpenBSD
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> CREATE TABLE person_hash (person_id integer, hash bigint, primary key (person_id, hash));
sqlite> INSERT INTO person_hash VALUES (285577, 306607097659338192312932577746542919680);
sqlite> INSERT INTO person_hash VALUES (285577, 306607097659338206333361532286405644297);
Error: UNIQUE constraint failed: person_hash.person_id, person_hash.hash
I have an account entity which contains a foreign key constraint for a user entity and customer entity.
I'm trying to validate the customer id is numeric and not null. Plus the unique constraint of user_id and customer_id.
My problem the Class Constraint UniqueEntity gets fired regardless of the outcome of the customer_id type: numeric validation result. Which throws a 500 because the customer_id column is an integer.
What I need to do is, validate the customer_id is a valid id (numeric and not null) before checking the unique constraint. Or is there any other way to avoid symfony/doctrine going to the db to test an invalid id?
My validation config,
MY\ApplicationBundle\Entity\Account:
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [ user_id, customer_id ]
message: Customer Id already exists for User
properties:
customer_id:
- Type:
type: numeric
message: Customer Id should be an integer.
- NotBlank:
message: Customer cannot be blank.
Group Sequences should solve your problem here. Something like that should work:
MY\ApplicationBundle\Entity\Account:
group_sequence:
- Basic
- Account
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [ user_id, customer_id ]
message: Customer Id already exists for User
properties:
customer_id:
- Type:
type: numeric
message: Customer Id should be an integer.
groups: [Basic]
- NotBlank:
message: Customer cannot be blank.
groups: [Basic]
With group sequences you can define the order of your validations. Basic checks all constraints with the group Basic and Account cheks the other constraints for this entity.