Postgresql setting next id to write to - mysql

I recently migrated a database from mysql to pgsql 9.
But now when I try to create a new object (in django admin) it tells me that the id I'm trying to use (started at one and has increased each time I tried) is already used.
I'm guessing that there is a pointer or index which needs to be set to the last used id. Am I correct?

When you define your table, the PostgreSQL equivalent to 'auto_increment' is:
CREATE TABLE foo (
id SERIAL,
...
);
If your table is already created (as I suspect it is), you can add this manually:
CREATE SEQUENCE foo_id_seq;
ALTER TABLE foo ALTER COLUMN id SET DEFAULT nextval('foo_id_seq');
Note that if you want to stick with the default name that Pg would have given you use the following format for your sequence name:
<table name>_<column name>_seq
Thus in my example, foo_id_seq.

If the table was migrated and it uses serial to replace the mysql auto increment column, your data was probably migrated without incrementing the serial sequence. Look up the postgresql setval function to set your sequence to a value above the highest existing key in your table.

Related

Getting id generated in a trigger for further requests

I have a table with two columns:
caseId, referring to a foreign table column
caseEventId, int, unique for a given caseId, which I want to auto-increment for the same caseId.
I know that the auto-increment option based on another column is not available in mySql with InnoDb:
MySQL Auto Increment Based on Foreign Key
MySQL second auto increment field based on foreign key
So I generate caseEventId into a trigger. My table:
CREATE TABLE IF NOT EXISTS mydb.caseEvent (
`caseId` CHAR(20) NOT NULL,
`caseEventId` INT NOT NULL DEFAULT 0,
PRIMARY KEY (`caseId`, `caseEventId`),
# Foreign key definition, not important here.
ENGINE = InnoDB;
And my trigger:
CREATE DEFINER=`root`#`%` TRIGGER `mydb`.`caseEvent_BEFORE_INSERT` BEFORE INSERT ON `caseEvent` FOR EACH ROW
BEGIN
SELECT COALESCE((SELECT MAX(caseEventId) + 1 FROM caseEvent WHERE caseId = NEW.caseId),0)
INTO #newCaseEventId;
SET NEW.`caseEventId` = #newCaseEventId;
END
With this, I get my caseEventId which auto-increments.
However I need to re-use this new caseEventId in further calls within my INSERT transaction, so I place this id into #newCaseEventId within the trigger, and use it in following instructions:
START TRANSACTION;
INSERT INTO mydb.caseEvent (caseId) VALUES ('fziNw6muQ20VGYwYPW1b');
SELECT #newCaseEventId;
# Do stuff based on #newCaseEventId
COMMIT;
This seems to work just fine but... what about concurrency, using connection pools etc...?
Is this #newCaseEventId variable going to be shared with all clients using the same connection, can I run into problems when my client server launches two concurrent transactions? This is using mysql under nodejs.
Is this safe, or is there a safer way to go about this? Thanks.
Edit 2020/09/24
FYI I have dropped this approach altogether. I was trying to use the db in a way it isn't meant to be used.
Basically I have dropped caseEventId, and any index which is supposed to increment nicely based on a given column value.
I rely instead on properly written queries on the read side, when I retrieve data, to recreate my caseEventId field...
That is no problem, the user defined variables a per client.
That means every user has its own use defined varoables
User-defined variables are session specific. A user variable defined by one client cannot be seen or used by other clients. (Exception: A user with access to the Performance Schema user_variables_by_thread table can see all user variables for all sessions.) All variables for a given client session are automatically freed when that client exits.
see manul

Auto increment column in mysql when importing with phpmyadmin

I have a table in mysql with the following headings:
staff_id,dept_id,role_id,username,firstname,lastname,passwd,backend,email,phone,phone_ext,mobile,signature,lang,timezone,locale,notes,isactive,isadmin,isvisible,onvacation,assigned_only,show_assigned_tickets,change_passwd,max_page_size,auto_refresh_rate,default_signature_type,default_paper_size,extra,permissions,created,lastlogin,passwdreset,updated
staff_id is a primary key value and is set to AUTO_INCREMENT.
I found the solution by Queue in this post really helpful, although when the data is being imported the staff_id column is not being auto-incremented. I am inserting the column names in the Format-Specific Options in phpmysql. I can only get it to populate if the staff_id value exists in the csv file I am trying to import.
So if the data looks like this:
2,1,1,agent,Mista,Busta,NULL,NULL,agent#company.org,,NULL,,,NULL,NULL,NULL,<p>this is an agent; mista busta; agent#company.org</p>,1,0,1,0,0,0,0,0,0,none,Letter,"{""def_assn_role"":true}","{""user.create"":1,""user.delete"":1,""user.edit"":1,""user.manage"":1,""user.dir"":1,""org.create"":1,""org.delete"":1,""org.edit"":1,""faq.manage"":1}",2020-02-04 10:18:42,NULL,NULL,2020-02-04 10:18:42
...note the first '2' is the staff_id. What I would like do is have this in the csv:
,1,1,agent,Mista,Busta,NULL,NULL,agent#company.org,,NULL,,,NULL,NULL,NULL,<p>this is an agent; mista busta; agent#company.org</p>,1,0,1,0,0,0,0,0,0,none,Letter,"{""def_assn_role"":true}","{""user.create"":1,""user.delete"":1,""user.edit"":1,""user.manage"":1,""user.dir"":1,""org.create"":1,""org.delete"":1,""org.edit"":1,""faq.manage"":1}",2020-02-04 10:18:42,NULL,NULL,2020-02-04 10:18:42
...leaving the staff_id column blank and allowing mysql to auto-populate (auto_increment) as it sees fit.
AUTO INCREMENT is set at the server level within MySQL, and can be overwritten if assigned manually within a CSV or other import. If you simply exclude the entire column from your import, you'll allow MySQL to do what is set as default for that column, and automatically assign ID's, since it doesn't think you want to assign them yourself.
Also as a side note, if you import more than once without using TRUNCATE TABLE -- MySQL will pick up on the last inserted ID and move on from there, even if the table is empty. So if you ever want to start over from 1 you'll have to trucate the table.

Insert into table with auto-increment field

I have two tables called HRData and HRDataHistory. HRDataHistory has the same structure as HRData except the first column is an autoincrement field and the last column is a DateTime field.
HRData has a trigger:
CREATE TRIGGER [HR].[HRData_History]
ON [HR].[HRData]
AFTER INSERT, UPDATE
AS
INSERT INTO HR.HRDataHistory
SELECT *, GETDATE()
FROM inserted
;
GO
This is working on an existing development machine. I am trying to mirror this relationship on my local sql server instance so that I can test some changes. Using SSMS I used 'Script Table as Create To...' and created the structure of each table and index on my local sql server instance. However when I do this for the trigger I get the following error:
An explicit value for the identity column in table 'HR.HRDataHistory' can only be specified when a column list is used and IDENTITY_INSERT is ON.
I know the preferred method would be to specify the columns, but I want to mirror production which does not currently do that and further I want to understand why it is working in production but not on my test database.
You're getting this error because you're trying to insert data into an IDENTITY column, which auto-populates itself whenever you insert another row in that table.
Off the top of my head, you can do something like below (although I believe there are more elegant solutions and I do not guarantee that this is a safe solution, nor have I tried something like this and I recommend testing on a TEST database before trying in production/LIVE):
add another column to HRDataHistory table which does not have identity set on it (because you cannot remove identity form a colum once set), but must have the same datatype as the current ID (IDENTITY) column
use a UPDATE query to move all of your ID's from your IDENTITY column to your new column:
UPDATE HRDataHistory
SET new_column = ID
Drop the IDENTITY column (but this might have grave implications if you have any FK set on it and possibly other objects that use it):
ALTER TABLE HRDataHistory
DROP COLUMN ID
Rename the "new_column" to the name of your previous IDENTITY column:
EXEC sp_RENAME 'HRDataHistory.new_column' , 'ID', 'COLUMN'
At this point I believe you can use your trigger to "copy" the newly inserted data from the HRData table into the HRDataHistory, since the column names should match and there is no more conflict due to IDENTITY.
Again, this might (not guaranteed) work so I recommend you first check on a TEST environment.

How do you change an autoincremented columns starting value through liquibase?

I am using MySql for my database. I have found how to set a column's starting autoincrement value when creating a table, but I need to know how to set a new starting value for an existing column. What does the liquibase script look like to do that?
The MySQL syntax is pretty straightforward:
ALTER TABLE mytable AUTO_INCREMENT = val ;
(Note that this is really a table attribute, not a column attribute. There can be only one column in a table declared to be AUTO_INCREMENT.)
This syntax isn't supported in SQL Server or Oracle; Oracle doesn't even have a concept of an "auto_increment" column, apart from a SEQUENCE object and a TRIGGER. SQL Server calls it an IDENTITY property. So I don't know how this statement would be represented in "liquibase" syntax, other than specifying that this statement is native MySQL syntax.
You can use addAutoIncrement (http://www.liquibase.org/documentation/changes/add_auto_increment.html) to change your existing AUTO_INCREMENT column.
Don't forget to specify columnDataType in the addAutoIncrement.
I used this yesterday for our project and it worked (for MySQL).

No such table SQLITE_SEQUENCE from AIR/Actionscript

I'm trying to reset the seed for an autoincrement field in SQLITE using AIR/ActionScript/Flex 4.5.
I'm doing what should normally work:
DELETE FROM SQLITE_SEQUENCE WHERE NAME = 'myTable'
I've checked that the database actually contains a SQLITE_SEQUENCE table. I'm able to execute the above statement without errors directly via the Firefox SQLITE plugin (SQLite Manager).
However, when I try to do the same using actionscript, I get an error:
No such table 'SQLITE_SEQUENCE'.
All I could find in searching around was this one guy who posted everywhere he could find - only to be left without an answer:
here
and
here
and
here
Any ideas?
sqlite_sequence table is not created, until you define at least one autoincrement and primary key column in your schema.
You should to insert "Auto increment" to primary key column
at least to one table,
Then SQLite is creating "SQLITE_SEQUENCE" table.
To get all tables have Auto increment:
SELECT * FROM SQLITE_SEQUENCE;