How to avoid primary key column duplication in PostgreSQL v 10? - postgresql-10

I am running a script to update a table structure, my problem is with the primary key column (id), the query creates a new id column each time I run my script.
This the first time that I am trying to write a script to update a database structure.
The database was created by an old version of an application,and now we want to release a new version of the application, but to achieve this goal I wrote a script which in summary is creating tables if they don't exist, adding columns to the tables if they don't exist, deleting old indexes and creating the new ones, etc.
The problem happens when the scripts add the primary key in the tables, in the database, the tables have a primary key column of type integer. But my query is not detecting this primary key column and it creates a new column with the same name and data type, at least that is what I see in PGAdmin v4.8.
Originally the primary key columns were created using the type serial and then PostgreSQL automatically creates a sequence and use it for the primary key.
How can I avoid the duplicated primary key columns?
Originally the column was created like follows
create table mytable(
id serial,
.
.
.
);
And if I look in the table, the column looks like this, which means that PostgreSQL created a sequence mytable_id_seq and used it for the auto increment value of primary key column.
id integer NOT NULL DEFAULT nextval('mytable_id_seq'::regclass)
But after I execute the following query and look in the table, it has a new column with the same name and data type like the one in the previous lines.
ALTER TABLE public.mytable ADD COLUMN IF NOT EXISTS id serial;
I am expecting to see only one column no matter how many times I execute the query.

Related

Primary and Foreign Key in DW tables

I've read that dimension tables hold the primary key and and fact tables contain the foreign key which references the primary key of Dimension tables.
Now the confusion I am having is this - suppose I have an ETL pipeline which populates the dimension table (let's say customer) from a source (say another DB). Let's assume this is a frequently changing table and has over 200 columns. How do I incorporate these changes in the dimension tables? I want to have only the latest record for each customer (type 1 SCD) in the DWH.
One thing what I could do is delete the row in the dimension table and re-insert the new updated row. But this approach won't work because of the primary key - foreign key constraint (which will not allow me to delete the record).
Should I write an update statement with all 200 columns in the ETL script? Or is there any other approach?
Strictly speaking you just need to update the fields that changed. But the cost of updating all in a single record is probably similar (assuming it’s row based storage), and it’s probably easier to write.
You can’t delete and re-insert, as the new row will have a new PK and old facts will no longer be linked.

EntityFramework Seed a table immediately after creation

I'm using EF6 Code First Migrations and ran into an issue where I created a new lookup table (Lookup) and established a required foreign key relationship with it (Table).
The (Table) already has records in it, so after adding the column I am backfilling the existing records (before the AddForeignKey method) with a default value to satisfy the required field requirement.
I have the (Lookup) table filling with Data in the Seed process.
The issue I am having is that when I run my code first migrations, I am getting a foreign key constraint error because in the migration Up code I am creating the foreign key relationship with the (Lookup) table and backfilling the records using the Sql command. But since the Seed method hasn't run yet, the (Lookup) table has no values in it, so the constraint fails.
Is there a way to execute that Fill without being redundant with the code in the Configuration.Seed method?

How can I replace records into another dataset?

I want to copy records of a few employees from one company into another larger one. If a primary key duplicate conflict occurs, the record has to be replaced. For Delphi DataSet there are commands "Insert", "Append", "Edit", and "Delete", but is there an easy way to "Replace" the record between the same tables, without knowing the full table structure or primary keys? There are like 30+ fields and they may be changed in the future.
In MySQL it would be REPLACE INTO table2 (SELECT * FROM table1) but I wanted to change a few fields in the target table, like employee's ID and department codes.
I'm afraid there is no way to replace/overwrite dataset records in Delphi. But using MySQL I can select the source data into a temp table, modify the temp table data, and place it into target table.

Should every table have a primary key using ADO.NET?

I'm using database-first approach with Oracle. One of my table doesn't have a primary key. It only has 2 columns which are foreign keys of other tables.
I have generated model in ASP.NET MVC project from database (Add - New Item - ADO.NET Entity Data Model).
But there is a problem - I get an error:
Error 159: EntityType 'DbModel.Store.SomeTableWithoutPK' has no key defined. Define the key for this EntityType. E:\Git_repo\ZZ\ZZ.Domain\DAL\DbModel.edmx
Does this mean that each table must have a primary key? Can I avoid this? Or I will be forced to add new column with a primary key to this table? Of course there is also possibility to apply primary key to multiple column, but is it necessary?
Every table should have a primary key for database efficiency and so that you can edit records.
You don't need to create a new column for the primary key in your 2 column table
In designer, select both columns and use both together as the primary key. As long as nulls are not allowed and there are no duplicates you should be OK.
Since this is a many to many table and you are using EF, you may find later that adding a datetime column to the table with getdate() as the default value will make data maintenance easier

Delphi 7 updating joined tables

I'm working with Delphi 7 and Firebird database. I'm using TIBDatabase, TIBTransaction, TIBQuery, TIBDataSet and DBGrid to establish connection and provide user interface for working with table. In my database I have two tables:
Ships
fields
Id integer
Name varchar(20)
Type_Id(Fk) integer
Longth integer
Ship_types
fields
Id(Pk) integer
Ship_type varchar(10)
So resulting dataset which I get through "join" query has such fields
Name
Type
Longth
Type is Ship_type field from Ship_types table joined via query by Type_Id foreign key to this table from Ships table.
Data is displaying properly.
Then I need to edit my data directly through DBGrid. For this purpose I use TIBUpdateSQL component. For displaying Type(lookup) field I chose DBGrid.Columns.PickList property.
So my question is how can I make TIBUpdateSQL work with such type of field? Cause I know that if it would be single table without foreign keys I have to write update statement into ModifySQL property of update component. But what have I do with fk fields? Can I write update join statement in UpdateSQL component or, if not, what else way I can do it?
I don't need to update two tables, I just need to update only Ships table but there is varchar(word representation) field in displaying dataset and in updating dataset it must be integer(corresponding id) to suit to table structure.
Editor in TIBUpdateSQL isn't solution for me cause I'm assigning query to TIBQuery on runtime.
You can't update tables using select with JOIN, only with subselects.
Sub-select example:
SELECT TABLE_NAME.*
, (SELECT TABLE_NAME2.NAME FROM TABLE_NAME2 WHERE TABLE_NAME2.ID = TABLE_NAME.ID)
FROM TABLE_NAME

Resources