Auto-incremented attribute assignment in sqlalchemy orm - postgresql

I have a table with the single auto-incremented field id of type bigserial:
create table user
(
id bigserial
primary key
);
I expect a new class instance to have a value of attribute 'id', but it is None:
>>> u = User()
>>> session.add(u)
>>> print(u.id)
None
However, if I execute a query statement, the attribute is there:
>>> session.query(User.id).all()
>>> print(u.id)
1
Why is field id empty on the first and not empty on the second call?

Related

How to reset the auto generated primary key in PostgreSQL

My class for the table topics is as below. The primary key is autogenerated serial key. While testing, I deleted rows from the table and was trying to re-insert them again. The UUID is not getting reset.
class Topics(db.Model):
""" User Model for different topics """
__tablename__ = 'topics'
uuid = db.Column(db.Integer, primary_key=True)
topics_name = db.Column(db.String(256),index=True)
def __repr__(self):
return '<Post %r>' % self.topics_name
I tried the below command to reset the key
ALTER SEQUENCE topics_uuid_seq RESTART WITH 1;
It did not work.
I would appreciate any form of suggestion!
If it's indeed a serial ID, you can reset the owned SEQUENCE with:
SELECT setval(pg_get_serial_sequence('topics', 'uuid'), max(uuid)) FROM topics;
See:
How to reset postgres' primary key sequence when it falls out of sync?
But why would the name be uuid? UUID are not integer numbers and not serial. Also, it's not entirely clear what's going wrong, when you write:
The UUID is not getting reset.
About ALTER SEQUENCE ... RESTART:
Postgres manually alter sequence
In order to avoid duplicate id errors that may arise when resetting the sequence try:
UPDATE table SET id = DEFAULT;
ALTER SEQUENCE seq RESTART;
UPDATE table SET id = DEFAULT;
For added context:
'table' = your table name
'id' = your id column name
'seq' = find the name of your sequence with:
SELECT pg_get_serial_sequence('table', 'id');

Mybatis Insert PK manually

I am trying to single insert data into table with assigned PK. Manually assiging PK.
XML file
<insert id = "insertStd" parameterType = "com.org.springboot.dao.StudentEntity" useGeneratedKeys = "false" keyProperty = "insertStd.id", keyColumn = "id">
INSERT INTO STUDENT (ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL )
VALUES (ID=#{insertStd.id}, NAME=#{insertStd.name}, BRANCH=#{insertStd.branch}, PERCENTAGE=#{insertStd.percentage}, PHONE=#{insertStd.phone}, EMAIL =#{insertStd.email});
</insert>
Service call method
public boolean saveStudent(Student student){
LOGGER.info("Student object save");
int savedId= studentMapper.insertStd(student);
}
Log file
org.springframework.jdbc.badsqlgrammarexception
### Error updating database Causes: cause org.postgresql.util.psqlexception error column id does not exist
HINT: There is a column named "id" in the table "student" but it can't be referenced from this part of the query.
Position 200
### Error may exist in file [c:\.....\StudentMapper.xml]
### Error may involve in com.org.springboot.dao.StudentMapper.insertStd-InLine
### The error occurred while setting parameters
### SQL INSERT INTO STUDENT (ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL )
VALUES (ID=?, NAME=?,BRANCH=?, PERCENTAGE=?, PHONE=?, EMAIL=?);
### cause org.postgresql.util.psqlexception ERROR column "id" doesn't exist. //It did worked with JPA id assigned manually.
### There is a column named "ID" in the table "STUDENT", Bbut it cannot be referenced from the part of the query.
The INSERT statement of malformed. The VALUES clause should not include the column names.
Also, since there's no primary auto-generation, you can remove all the other attributes. Just leave the mapper id.
Note: if you want to manually assign the PK value, you need to make sure the table does not have a GENERATED ALWAYS clause for the column. If this is the case, the table will ignore the value you are providing and will use its own rules to generate the PK.
Use:
<insert id="insertStd">
INSERT INTO STUDENT (ID, NAME, BRANCH, PERCENTAGE, PHONE, EMAIL)
VALUES (
#{insertStd.id}, #{insertStd.name}, #{insertStd.branch},
#{insertStd.percentage}, #{insertStd.phone}, #{insertStd.email}
);
</insert>
Your error is easily reproduceable:
create table t (a int, b varchar(10));
insert into t (a, b) values (123, 'ABC'); -- succeeds
insert into t (a, b) values (a=123, b='ABC'); -- fails!
error: column "a" does not exist
See the Fiddle.

Auto increment non primary column in SQLAlchemy

In my db model I need userId and forumPostId to be a composite primary key. But I need id to be a auto incremented value. But when I'm trying to insert new row in table getting none in id instead of a auto incremented integer.
class ForumPostFollow(db.Model):
__tablename__ = "forum_post_follow"
id = db.Column(db.Integer,autoincrement=True,nullable=False,unique=True)
userId = db.Column(db.Integer,db.ForeignKey('user.id'),primary_key=True)
forumPostId = db.Column(db.Integer,db.ForeignKey('forum_post.id'),primary_key=True)
active = db.Column(db.Boolean,nullable=False)
My package versions
Flask-SQLAlchemy==2.3.2 SQLAlchemy>=1.3.0
This question is similar to this question. But it's for version 1.1
Updated Question
I've changed my id columns sequence from terminal
ALTER TABLE forum_post_follow DROP COLUMN id;
ALTER TABLE forum_post_follow ADD COLUMN id SERIAL;
Then my altered columns looks like this
But still getting same error
sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) null value in column "id" violates not-null constraint
DETAIL: Failing row contains (1, 1, t, null).
[SQL: INSERT INTO forum_post_follow (id, "userId", "forumPostId", active) VALUES (%(id)s, %(userId)s, %(forumPostId)s, %(active)s)]
[parameters: {'id': None, 'userId': 1, 'forumPostId': 1, 'active': True}]
I had a similar problem and found that as per SQLAlchemy 1.3 Documentation:
For the case where this default generation of IDENTITY is not desired, specify False for the Column.autoincrement flag, on the first integer primary key column:
so you might want to try this:
class ForumPostFollow(db.Model):
__tablename__ = "forum_post_follow"
id = db.Column(db.Integer,autoincrement=False,primary_key=True,nullable=False,unique=True)
userId = db.Column(db.Integer,db.ForeignKey('user.id'),primary_key=True)
forumPostId = db.Column(db.Integer,db.ForeignKey('forum_post.id'),primary_key=True)
active = db.Column(db.Boolean,nullable=False)

IBM DB2 recreate index on truncated table

After truncating table, and inserting new values in table, auto-increment values are not set to started value 1. When inserting new values it's remember last index-ed value of auto-increment.
Colum in table named: ID
Index: PRIMARY,
Initial Value: 1
Cache size: 1
Increment: 1
[checked on IBM DB2 Control Center]
This query:
TRUNCATE TABLE ".$this->_schema.$table." DROP STORAGE IGNORE DELETE TRIGGERS IMMEDIATE
table is EMPTY.
After INSERT NEW VALUES example: INSERT INTO DB2INST1.db (val) VALUES ('abc') it's INSERT with LAST
ID | val
55 | abc
But it SHOULD BE:
ID | val
1 | abc
I'm guessing here that your question is "how do you restart the IDENTITY sequence?" If that is the case, then you can reset it with the following SQL:
ALTER TABLE <table name> ALTER COLUMN <IDENTITY column> RESTART WITH 1
However, like #Ian said, what you are seeing is the expected behavior of a TRUNCATE.
First select in TABLE SCHEMA WHERE is name of IDENTITY column:
Query 1:
SELECT COLNAME FROM SYSCAT.COLUMNS WHERE TABSCHEMA = 'DB2INST1' AND
TABNAME = 'DB' AND IDENTITY = 'Y'
Then, truncate table and return it's example: ID for altering index:
Query 2:
This ID puts on query for reset and altering index identity:
ALTER TABLE DB2INST1.DB ALTER COLUMN ID RESTART WITH 1
Change ID above returned from Query 1, which returns name of ID to Query 2.
SOLVED!

How to insert DB Default values under EF?

when adding a new record like this
ContentContacts c2 = new ContentContacts();
c2.updated_user = c2.created_user = loggedUserId;
c2.created_date = c2.updated_date = DateTime.UtcNow;
db.ContentContacts.AddObject(c2);
I'm getting
Cannot insert the value NULL into column 'main_email_support', table 'SQL2008R2.dbo.ContentContacts'; column does not allow nulls. INSERT fails. The statement has been terminated.
but the default value in the database is an empty string like:
why am I getting such error? shouldn't the EF says something like:
"ohh, it's a nullvalue, so let's add the column default value instead"
I did a small test, created a table with a column that had a default value but did not allow nulls.
Then this SQL Statement:
INSERT INTO [Test].[dbo].[Table_1]
([TestText])
VALUES
(null)
Gives this error:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'TestText', table
'Test.dbo.Table_1'; column does not allow nulls. INSERT fails.
The problem here is that the insert specifies all the columns, also those with default values. The the Insert tries to update the columns with null values.
You have 2 options:
Update the table through a view, which does not contain the default columns
Set the default values in your C# code
A default value is business logic, so there is a case for it being set in the business layer of your application.