Inserting new entity does not look at 'SEQUENCE_GENERATOR' - demo admin - broadleaf-commerce

I am using SQL Server 2012 Express Edition with hibernate SQLServer2008Dialect dialect to run the Admin demo and have some troubles with primary key generation. The initial insert statement do not use the pre-calculated values from 'SEQUENCE_GENERATOR' for the #Id field.
#Id
#GeneratedValue(generator = "StructuredContentFieldId")
#GenericGenerator(
name="StructuredContentFieldId",
strategy="org.broadleafcommerce.common.persistence.IdOverrideTableGenerator",
parameters = {
#Parameter(name="segment_value", value="StructuredContentFieldImpl"),
#Parameter(name="entity_name", value="org.broadleafcommerce.cms.structure.domain.StructuredContentFieldImpl")
}
)
#Column(name = "SC_FLD_ID")
protected Long id;
When trying to insert new Structured Content, 'SEQUENCE_GENERATOR' table gets some values populated:
SELECT * FROM dbo.SEQUENCE_GENERATOR
ID_NAME ID_VAL
--------------------------- --------------------
SandBoxImpl 101
StructuredContentFieldImpl 101
StructuredContentImpl 101
But the new entity is saved with the id of 1 (there are some existing rows already in this table as per demo sql script):
SELECT SC_ID, CONTENT_NAME, SC_TYPE_ID FROM dbo.BLC_SC
SC_ID CONTENT_NAME SC_TYPE_ID
-------------------- ------------------------------------------ --------------------
1 html test 2
100 Buy One Get One - Twice the Burn 1
[...]
156 Home Page Featured Products Title 3
The following sql shows up in the console when inserting that row:
[artifact:mvn] Hibernate: select tbl.ID_VAL from SEQUENCE_GENERATOR tbl with (updlock, rowlock ) where tbl.ID_NAME=?
[artifact:mvn] Hibernate: update SEQUENCE_GENERATOR set ID_VAL=? where ID_VAL=? and ID_NAME=?
[artifact:mvn] Hibernate: insert into BLC_SC (ARCHIVED_FLAG, CREATED_BY, DATE_CREATED, DATE_UPDATED, UPDATED_BY, CONTENT_NAME, DELETED_FLAG, LOCALE_CODE, LOCKED_FLAG, OFFLINE_FLAG, ORIG_ITEM_ID, ORIG_SANDBOX_ID, PRIORITY, SANDBOX_ID, SC_TYPE_ID, SC_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Later on saving some HTML content into the BLC_SC_FLD isn't that lucky. New entity also gets assigned the id of 1, which unfortunately already exists:
SELECT SC_FLD_ID, FLD_KEY, VALUE, SC_ID FROM dbo.BLC_SC_FLD
SC_FLD_ID FLD_KEY VALUE SC_ID
------------- ------------- --------------------------------------------- --------
1 imageUrl /img/banners/buy-one-get-one-home-banner.jpg 100
and of course the exception is thrown:
[artifact:mvn] Hibernate: update SEQUENCE_GENERATOR set ID_VAL=? where ID_VAL=? and ID_NAME=?
[artifact:mvn] Hibernate: insert into BLC_SC_FLD (CREATED_BY, DATE_CREATED, DATE_UPDATED, UPDATED_BY, FLD_KEY, LOB_VALUE, VALUE, SC_ID, SC_FLD_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
[artifact:mvn] 2014-05-06 00:58:02.191:WARN:oejs.ServletHandler:/admin/structured-content/1
[artifact:mvn] org.springframework.dao.DataIntegrityViolationException: Violation of PRIMARY KEY constraint 'PK__BLC_SC_F__8A534C1863E06FD9'. Cannot insert duplicate key in object 'dbo.BLC_SC_FLD'. The duplicate key value is (1).; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Violation of PRIMARY KEY constraint 'PK__BLC_SC_F__8A534C1863E06FD9'. Cannot insert duplicate key in object 'dbo.BLC_SC_FLD'. The duplicate key value is (1).
I am not sure where is the problem. The #GenericGenerator generation strategy org.broadleafcommerce.common.persistence.IdOverrideTableGenerator seems to hit 'SEQUENCE_GENERATOR' on first insert and then increments the id from FIELD_CACHE variable as designed.
So I have actually 2 questions.
Why 'SEQUENCE_GENERATOR' gets initial values of 101, when there is already higher id saved in the table?
Why the entity is being saved with the value of 1? Is this MS SQL Server related?

Ok resolved :) Broadleaf has 3 persistence units, and by default they point to the same database, but only one (blPU) persistence unit imports sql at the start of the demo.
So by doing this:
blPU.hibernate.hbm2ddl.auto=create-drop
blCMSStorage.hibernate.hbm2ddl.auto=create-drop
blSecurePU.hibernate.hbm2ddl.auto=create-drop
I made the SEQUENCE_GENERATOR to be dropped and recreated empty by other persistence unit in line.
This works fine:
blPU.hibernate.hbm2ddl.auto=create-drop
blCMSStorage.hibernate.hbm2ddl.auto=update
blSecurePU.hibernate.hbm2ddl.auto=update
Dooh!

Related

How to insert into table with max(ordering) + 1 in ordering column?

I have a chapters table with a ordering column(integer) in Postgres. How to insert/create a new row with ordering set to MAX(ordering) + 1 in diesel? I've tried using raw sql as following:
INSERT INTO chapters
(id, name, user_id, book_id, ordering, date_created, date_modified)
SELECT ?, ?, ?, ?, IFNULL(MAX(ordering), 0) + 1, ?, ?
FROM chapters
WHERE book_id = ?;
and insert into by:
let id = Uuid::new_v4().to_string_id();
let now = Utc::now().naive_utc();
diesel::sql_query(INSERT_CHAPTER)
.bind::<Text, _>(&id)
.bind::<Text, _>(name)
.bind::<Text, _>(uid)
.bind::<Text, _>(bid)
.bind::<Timestamp, _>(&now)
.bind::<Timestamp, _>(&now)
.bind::<Text, _>(bid)
.execute(conn)?;
It works on Sqlite3 backend, but fails on Pg backend with following error message:
"syntax error at or near \",\""
Use $N as placeholders for Postgres and ? for sqlite3.

if else statement with mulitple variables

i need an if else statement in sqlite3 query, but i can't find the error.
if the name is available it should update the variable disabled. if the name does not exist, insert it
name = 'testname'
disabled = 'x'
finish = '1'
runtime = '1'
c.execute("IF EXISTS(SELECT name FROM infos WHERE name=?', (name,)) THEN UPDATE infos SET disabled=? WHERE name=?', (disabled,name) ELSE INSERT INTO infos VALUES (?, ?, ?, ?, ?);", (None, name, disabled, finish, runtime))
error:
sqlite3.OperationalError: near "IF": syntax error
I've tried this command too, but I suspect the python command is wrong:
c.execute("INSERT INTO infos VALUES (?, ?, ?, ?, ?) ON CONFLICT(?) DO UPDATE SET disabled = (?);", (None, name, disabled, finish, runtime),(name),(disabled))
If your version of SQLite is 3.24.0+ and you have defined the column name as UNIQUE (or PRIMARY KEY) you can use UPSERT, like this:
name = 'testname'
disabled = 'x'
finish = '1'
runtime = '1'
sql = """
INSERT INTO infos(name, disabled, finish, runtime) VALUES (?, ?, ?, ?)
ON CONFLICT(name) DO UPDATE
SET disabled = excluded.disabled, finish = excluded.finish, runtime = excluded.runtime"""
c.execute(sql, (name, disabled, finish, runtime))
See how it works in SQLite in this demo.

Unable to use Parameter in Insert statement in python?

Taking INS_QUERY value from Audit table.
INS_QUERY = ("INSERT INTO sales.dbo.Customer_temp (ID,FIRST_NM,LAST_NM,CITY,COUNTRY,PHONE) VALUES ('%s','%s','%s','%s','%s','%s')" % (d[0],d[1],d[2],d[3],d[4],d[5]))
cursor = cs.cursor()
cursor.execute(INS_QUERY)
cs.commit();
if I hard coded the INS_QUERY value in script it's working fine but if I take same value from table it's giving below error message.
Error Message:
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL
Server Driver][SQL Server]Incorrect syntax near 'INSERT INTO
sales.dbo.Customer_temp (ID,FIRST_NM,LAST_NM,CITY,COUNTRY,PHONE)
VALUES ('%s','%s','%s','%s','%s','%s')'. (102) (SQLExecDirectW)")
Audit Table Insert query:
INSERT INTO DBO.AUDIT_TABLE(INST_QUERY) VALUES ('("INSERT INTO sales.dbo.Customer_temp (ID,FIRST_NM,LAST_NM,CITY,COUNTRY,PHONE) VALUES ("%s","%s","%s","%s","%s","%s")" % (d[0],d[1],d[2],d[3],d[4],d[5]))')
You are using pyodbc connector and the parameters syntax is ?, not %s
The second detail is that when the parameters are from type str, there is no need to use single quotes '?', this is done for you automatically.
Can you try this approach and tell me how it works for you?
INS_QUERY = "INSERT INTO sales.dbo.Customer_temp (ID,FIRST_NM,LAST_NM,CITY,COUNTRY,PHONE) VALUES (?, ?, ?, ?, ?, ?)"
cursor = cs.cursor()
cursor.execute(INS_QUERY, (d[0],d[1],d[2],d[3],d[4],d[5]) )
cs.commit();

invalid column name error when writing pandas DataFrame to sql

When I try to write a dataframe to ms sql server, like this:
cnxn = sqlalchemy.create_engine("mssql+pyodbc://#HOST:PORT/DATABASE?driver=SQL+Server")
df.to_sql('DATABASE.dbo.TABLENAME', cnxn, if_exists='append', index=False)
I get the following error:
ProgrammingError: (pyodbc.ProgrammingError) ('42S22', "[42S22] [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'DateDay'. (207) (SQLExecDirectW)") [SQL: 'INSERT INTO [DATABASE.dbo.TABLENAME] ([DateDay], [ID], [Code], [Forecasted], [Lower95CI], [Upper95CI], [ForecastMethod], [ForecastDate]) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'] [parameters: ((datetime.datetime(2017, 12, 10, 0, 0), '8496', "'IO'", 197, 138, 138, 'ARIMAX',...
it seems that the column name is producing the error? it is looking for [DateDay] but it finds 'DateDay' with the ' '? how to fix this?
I am using python 3.6 on a windows machine, pandas 0.22, sqlalchemy 1.1.13 and pyodbc 4.0.17
UPDATE-- SOLUTION FOUND:
So I realized that my mistake was in the tablename which calls the database: 'DATABASE.dbo.TABLENAME', when i removed the DATABASE.dbo, it worked:
df.to_sql('TABLENAME', cnxn, if_exists='append', index=False)
The problem was that I added the database name when executing the df.to_sql command, which was not needed since I had already established a connection to that database. This worked:
df.to_sql('TABLENAME', cnxn, if_exists='append', index=False)
The problem also may happen if the name you defined in the database table and the name you defined in the dataframe for the same column is different. For example, 'items' and 'itens' will not match and this will cause an error when your script tries to record the dataframe into the database.

SQLite Operational Error in text column

I am getting
sqlite3.OperationalError: near "[24:-2]": syntax error
when inserting values into a table. I am using Python and [24:-2] is to trim a very long string. The string is around 12.000 characters long and the table column is defined as TEXT.
Can you enlighten me why I am getting the error?
Python and SQL are two different languages.
To get Python values into SQL, use parameters:
CUR.execute("INSERT INTO de VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
(m_id, start, s_zip, s_lat, s_lon, dest, d_lat, d_lon, dist, tid, j_str[24:-2]))

Resources