Adding column with foreign key into table. - postgresql

I have some problem. I want to add new column into my table that references to other column in other table. I do something like that:
class m161202_153033_dodanie_informacji_o_obsludze_prawnej_do_pozyczki extends CDbMigration
{
public function safeUp()
{
$this->execute("ALTER TABLE loan ADD COLUMN administrator int NOT NULL DEFAULT 15 REFERENCES person (id) ON UPDATE CASCADE ON DELETE NO ACTION;");
}
public function safeDown()
{
$this->execute("ALTER TABLE loan DROP COLUMN administrator;");
}
}
But when i try to execute this migration i have this error:
Foreign key violation: 7
DETAIL: Key (administrator)=(15) doesn't appear in table "person"..
I know that there is no suck column "administrator" in my table. But i want to add new column "administrator" into loan table. I wanted to make "administrator" foreign key from person table, column "id". Can u help me, what am i doing wrong?

The error means that there is no row in person with id equal to 15, which would be required for the constraint to be fulfilled.
When you run that ALTER TABLE statement, the table has to be rewritten, and the new column is filled with the value 15.
Often it is easier to create a new column nullable and without default value (then ALTER TABLE will not rewrite the table) and use UPDATE to populate the new column. After that you can change the column definition to NOT NULL and add a default value.

Try this
class m161202_153033_dodanie_informacji_o_obsludze_prawnej_do_pozyczki extends CDbMigration
{
public function safeUp()
{
$this->execute("INSERT INTO person (id) VALUES (15) ON CONFLICT (id) DO NOTHING;");
$this->execute("ALTER TABLE loan ADD COLUMN administrator int NOT NULL DEFAULT 15 REFERENCES person (id) ON UPDATE CASCADE ON DELETE NO ACTION;");
}
public function safeDown()
{
$this->execute("ALTER TABLE loan DROP COLUMN administrator;");
}
}

Related

SequelizeJS - Drop old pkey column

I created a new int8 column (id_int8) for a table and copied all of the ids into the column. I'd now like to write a migration that will rename the new column to id and delete the old id column. But I've gotten the error ERROR: Unknown constraint error.
import { QueryInterface } from 'sequelize';
export default {
up: async (queryInterface: QueryInterface): Promise<void> => {
await queryInterface.sequelize.query(
`
BEGIN;
LOCK TABLE table IN EXCLUSIVE MODE;
ALTER TABLE table DROP CONSTRAINT table_pkey, ADD CONSTRAINT table_pkey PRIMARY KEY USING INDEX id_int8_unique;
ALTER SEQUENCE table_id_seq OWNED BY table.id_int8;
ALTER TABLE table ALTER COLUMN id_int8 SET DEFAULT nextval('table_id_seq');
ALTER TABLE table DROP COLUMN id;
ALTER TABLE table RENAME COLUMN id_int8 TO id;
COMMIT;
`,
);
},
down: async (): Promise<void> => {
// no-op transaction
},
};
I can see that I have the index "table_pkey" PRIMARY KEY, btree (id)

I can't manually add foreign keys in golang gorm

I am trying to add a foreign key manually in gorm but i get this error
db.Model(&models.Business{}).AddForeignKey undefined (type *gorm.DB has no field or method AddForeignKey)
am using postgres
i have tried
db.Model(&Business{}).AddForeignKey("cust_id", "customers(cust_id)", "CASCADE", "CASCADE")
you can do it with two solution that i know in GORM
#1
when you create model you do it like below:
type Business struct {
Name string
CustomersID int
Customers Customers `gorm:"foreignKey:CustomersID"` // use CustomersID as foreign key
}
type Customers struct {
ID int
Name string
}
#2
every time you want you can add foreign key like below
Client.Exec("ALTER TABLE business ADD FOREIGN KEY (cust_id)" +
"REFERENCES customers (id) ON DELETE CASCADE ON UPDATE CASCADE;")

Selecting Postgres UUID's on Laravel

I have a table on Postgres that auto generates UUIDs, when I dd Customer::all(); on Laravel I get an array with "cs_id" => "d0402be5-e1ba-4cb2-a80c-5340b406e2c3" which is fine. When I loop or select one record with the only the cs_id the data it retuns 0,2,5 for the three records currently on the table which is incorrect data.
EDIT:
CREATE TABLE customers
(
cs_id character varying(255) NOT NULL DEFAULT gen_random_uuid(),
CONSTRAINT cs_customers_pkey PRIMARY KEY (cs_id),
}
On laravel
$customerData = Customer::where('cs_id','d0402be5-e1ba-4cb2-a80c-5340b406e2c3')->first();
dd($customerData['cs_id']);
For some reason Eloquent messes up there.
just add a getter and use it whenever you need the cs_id
public function getGuid()
{
return $this->attributes['cs_id'];
}
To use uuids auto-generated by the database, define your model as follows:
class Customer extends Model
{
// rename the id column (optional)
protected $primaryKey = 'cs_id';
// tell Eloquent that your id is not an integer
protected $keyType = 'string';
// do NOT set $incrementing to false
}
Then you can use all Eloquent's methods as you would with classic ids:
$customerData = Customer::findOrFail('d0402be5-e1ba-4cb2-a80c-5340b406e2c3');
Use Customer::findOrFail('d0402be5-e1ba-4cb2-a80c-5340b406e2c3');
to get the record matching that pk.
I'm assuming on top you have use App\Customer;

EntityFramework - many-to-many reference in the DB without a backreference in the model

In my application users can define Parameters, and then create SlideSets based on a grouping of parameters.
I am using code-first Entity Framework 5.0 and I have the following model:
class SlideSet {
public ICollection<Parameter> Parameter
}
class Parameter {}
A parameter might be used by many slidesets or none at all. However, in my domain a parameter has no need to reference a SlideSet, they are in separate bounded contexts (both SlideSet and Parameter are Aggregate Roots). As such, I don't want to put a reference from Parameter to SlideSet.
The table model (I don't care about table/column names) that I want is
Table SlideSet
Table Param
Table SlideSetParam
FK_SlideSet
FK_Param
I know I could model this by introducing a ParameterGroup entity or a Param.SlideSets collection, but it would exist solely for ORM mapping purposes (and cause serialization issues). Is there any other way to tell EF to generate this table model from my entities?
This should make you a Parameter w/o a navigation property:
modelBuilder.Entity<SlideSet>()
.HasMany(x => x.Parameters)
.WithRequired();
EDIT:
Based on the comment - that should be all together similar. This seems to work nicely what you're trying to do....
modelBuilder.Entity<SlideSet>()
.HasMany(x => x.Parameters)
.WithMany();
...and you can use it either way:
var slideset = new SlideSet { Parameters = new []
{
new Parameter{},
new Parameter{},
new Parameter{},
new Parameter{},
}
};
var slideset2 = new SlideSet { };
db.SlideSets.Add(slideset);
db.SaveChanges();
var slidesets = db.SlideSets.ToList();
var parameters = db.Parameters.ToList();
Console.WriteLine("");
db.SlideSets.Add(slideset2);
db.SaveChanges();
slidesets = db.SlideSets.ToList();
parameters = db.Parameters.ToList();
Console.WriteLine("");
...and the SQL:
CREATE TABLE [dbo].[Parameters] (
[ParameterID] [int] NOT NULL IDENTITY,
CONSTRAINT [PK_dbo.Parameters] PRIMARY KEY ([ParameterID])
)
CREATE TABLE [dbo].[SlideSets] (
[SlideSetID] [int] NOT NULL IDENTITY,
CONSTRAINT [PK_dbo.SlideSets] PRIMARY KEY ([SlideSetID])
)
CREATE TABLE [dbo].[SlideSetParameters] (
[SlideSet_SlideSetID] [int] NOT NULL,
[Parameter_ParameterID] [int] NOT NULL,
CONSTRAINT [PK_dbo.SlideSetParameters] PRIMARY KEY ([SlideSet_SlideSetID], [Parameter_ParameterID])
)
CREATE INDEX [IX_SlideSet_SlideSetID] ON [dbo].[SlideSetParameters]([SlideSet_SlideSetID])
CREATE INDEX [IX_Parameter_ParameterID] ON [dbo].[SlideSetParameters]([Parameter_ParameterID])
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.SlideSets_SlideSet_SlideSetID] FOREIGN KEY ([SlideSet_SlideSetID]) REFERENCES [dbo].[SlideSets] ([SlideSetID]) ON DELETE CASCADE
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.Parameters_Parameter_ParameterID] FOREIGN KEY ([Parameter_ParameterID]) REFERENCES [dbo].[Parameters] ([ParameterID]) ON DELETE CASCADE
...this makes the original tables practically 'agnostic' of the relationships (many-to-many) - while index table is automatically generated in the background.
You can also further customize that and make your own SlideSetParam (e.g. if you'd want to add additional fields there) with pretty much the same layout - just Parameters would have to point to that instead.

I dont want to insert the PK val.But - Cannot insert explicit value for identity column in table 'Employees' when IDENTITY_INSERT is set to OFF

I am using the Entity Framework to update my database.
The Employee table has an employeeId primary key field.
When I instantiate an employee object, the employeeId defaults to zero.
I want to insert the employee object into the database, ignoring the primary key value of zero.
Yet I get this exception;
Cannot insert explicit value for identity column in table 'Employees' when IDENTITY_INSERT is set to OFF.
What should I be doing to stop this?
public void Add()
{
using (SHPContainerEntities db = new SHPContainerEntities())
{
// Set default values
this.StartDate = DateTime.Now;
// Start date now
this.SHP_UserRoleId = db.SHP_UserRoles.Where(x => x.RoleName == "Employee").Single().UserRoleId;
// Default user role is "Employee". This can be changed later.
this.DepartmentId = 1;
// This is a temporary fix.
db.AddToEmployees(this);
//db.Employees.AddObject(this);
db.SaveChanges();
}
}
I fixed the problem.
I updated the database and I forgot to update my edmx file to reflect that change.