NHibernate bug sql generator - sql-server

i have class named Group
i tried to test configuration:
var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly(typeof (Group).Assembly);
new SchemaExport(cfg).Execute(true, true, false);
when i debug this, im getting following sql:
create table Group (
ID INT IDENTITY NOT NULL,
Name NVARCHAR(255) null,
CreatedDate DATETIME null,
primary key (ID)
)
so like i remember, Group key reserved for Group By
so why NHibernate does not uses quotes like Group for table names?
BTW, I'm using Sql Server 2005 and NHibernate 2.1

If you are using a reserved keyword as your object name you should mark it with a DBMS specific sign. For example if you are using SQL Server you should put it in [] and use ` for MySql.
In this example you should write (assuming that you are using SQL server) :
<class name="Group" table="[Group]">

Related

Cannot insert the value NULL into column 'id', table 'XXX'; column does not allow nulls

I have the below model:
class Loan(models.Model):
id = models.BigAutoField(primary_key=True)
date = models.DateField(default=timezone.now)
description = models.TextField(max_length=255)
When I try to save date and description I get the above error
below is my admin.py file:
#admin.register(Loan)
class LoanAdmin(admin.ModelAdmin):
pass
and below is my table created through migrations:
Django 3.2.6.
How can I solve this?
SQL Server version is Microsoft SQL Server 2019 (RTM-CU8-GDR)
I tried :
class Loan(models.Model):
date = models.DateField(default=timezone.now)
description = models.TextField(max_length=255)
The solution that worked to this problem was to delete all migrations and create new migrations.
you don't need to add id column specifically. Django creates id column itself.
class Loan(models.Model):
date = models.DateField(default=timezone.now)
description = models.TextField(max_length=255)
This should work.
Also, if you want to add custom id column check this

SQLAlchemy and mssql : how to create unique constraint with multiple null value

I am working with SQLAlchemy and MS SQL server and I would like to create a unique constraint that allows multiple NULL value.
I know that MS SQL server does not ignore the null value and considers it as violation for the UNIQUE KEY.
I also know how to fix it with SQL code (see here)
But is there a way to do the same thing with SQLAlchemy directly ?
Here is my code :
class Referential(db.Model):
__tablename__ = "REFERENTIAL"
id = db.Column("ID", Integer, primary_key=True, autoincrement=True)
name = db.Column("NAME", String(100), index=True, unique=True, nullable=False)
internal_code = db.Column("INTERNAL_CODE", String(50), unique=True, index=True)
Thanks in advance
MSSQL's implementation when it comes to allowing nulls in a unique column is a little odd.
import sqlalchemy as sa
sa.Table(
sa.Column('column', sa.String(50), nullable=True),
sa.Index('uq_column_allows_nulls', mssql_where=sa.text('column IS NOT NULL'),
)
If you are planning on using alembic like I was this is the code:
import sqlalchemy as sa
import alembic as op
op.create_index(
name='uq_column_name',
table_name='table',
columns=['column'],
mssql_where=sa.text('column IS NOT NULL'),
)
This uses the sql expression text for sqlalchemy and create_index's dialect_expression key word arguments mssql_where=

How to fetch generated sequence ID using JdbcTemplate on SQL Server 2012+

I have a table in SQL Server 2012 that uses a Sequence to generate the primary key using a default constraint.
CREATE TABLE [vfm].[ChangeEvent](
[ChangeEventId] [int] NOT NULL,
[Description] [varchar](100) NOT NULL,
[LegalEffectiveDate] [date] NOT NULL,
[StatusCode] [char](1) NOT NULL,
CONSTRAINT [PK_ChangeEvent] PRIMARY KEY CLUSTERED
(
[ChangeEventId] ASC
)
ALTER TABLE [vfm].[ChangeEvent] ADD CONSTRAINT [DF_ChangeEvent_1] DEFAULT
(NEXT VALUE FOR [vfm].[SEQ_ChangeEventId]) FOR [ChangeEventId]
I'm using NamedParameterJdbcTemplate in Spring 5.x to insert a new record into the table.
StringBuilder sql = new StringBuilder()
.append("insert into vfm.ChangeEvent(Description, LegalEffectiveDate, StatusCode)")
.append(" values (:description, :legalEffectiveDate, :status)");
SqlParameterSource parameters = new MapSqlParameterSource()
.addValue("description", changeEvent.getDescription())
.addValue("legalEffectiveDate", changeEvent.getLegalEffectiveDate())
.addValue("status", "S");
KeyHolder keyHolder = new GeneratedKeyHolder();
namedParameterJdbcTemplate.update(sql.toString(), parameters, keyHolder, new String[] { "ChangeEventId" });
From what I've seen so far, my KeyHolder comes back empty, GENERATED_KEYS = null. Is it possible to configure the .update call to retrieve the generated ChangeEventId? Or am I stuck because the table is using a sequence object?
I believe this is possible with Oracle, but I haven't seen any answers for SQL Server. The SQL Server questions I've seen have used identity columns, not sequences.
Here's what ended up working for me.
Use output insert.<id> in the SQL query to return the inserted value
Use queryForObject instead of update on NamedParameterJdbcTemplate
Make sure the sequence is set up as the column default
StringBuilder sql = new StringBuilder()
.append("insert into vfm.ChangeEvent(Description, LegalEffectiveDate, StatusCode)")
.append(" output inserted.ChangeEventId")
.append(" values (:description, :legalEffectiveDate, :status)");
SqlParameterSource parameters = new MapSqlParameterSource()
.addValue("description", changeEvent.getDescription())
.addValue("legalEffectiveDate", changeEvent.getLegalEffectiveDate())
.addValue("status", "S");
Integer changeEventId = namedParameterJdbcTemplate.queryForObject(sql.toString(), parameters, Integer.class);

How to make the 'public' schema default in a Scala Play project that uses PostgreSQL?

I am not sure if my issue connecting to the Scala Play 2.5.x Framework or to PostgreSQL so I am going to describe my setup.
I am using the Play 2.5.6 with Scala and PostgreSQL 9.5.4-2 from the BigSQL Sandboxes. I use the Play Framework default evolution package to manage the DB versions.
I created a new database in BigSQL Sandbox's PGSQL and PGSQL created a default schema called public. I use this schema for development.
I would like to create a table with the following script (1.sql in DB evolution config):
# Initialize the database
# --- !Ups
CREATE TABLE user (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL,
creation_date TIMESTAMP NOT NULL
);
# --- !Downs
DROP TABLE user;
Besides that I would like to read the table with a code like this:
val resultSet = statement.executeQuery("SELECT id, name, email FROM public.user WHERE id=" + id.toString)
I got an error if I would like to execute any of the mentioned code or even if I use the CREATE TABLE... code in pgadmin. The issue is with the user table name. If I prefix it with public (i.e. public.user) everything works fine.
My questions are:
Is it normal to prefix the table name with the schema name every time? It seems to odd to me.
How can I make the public schema a default option so I do not have to qualify the table name? (e.g. CREATE TABLE user (...); will not throw an error)
I tried the following:
I set the search_path for my user: ALTER USER my_user SET search_path to public;
I set the search_path for my database: ALTER database "my_database" SET search_path TO my_schema;
search_path correctly shows this: "$user",public
I got the following errors:
In Play: p.a.d.e.DefaultEvolutionsApi - ERROR: syntax error at or near "user"
In pgadmin:
ERROR: syntax error at or near "user"
LINE 1: CREATE TABLE user (
********** Error **********
ERROR: syntax error at or near "user"
SQL state: 42601
Character: 14
This has nothing to do with the default schema. user is a reserved word.
You need to use double quotes to be able to create such a table:
CREATE TABLE "user" (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL,
creation_date TIMESTAMP NOT NULL
);
But I strongly recommend not doing that. Find a different name that does not require a quoted identifier.

Play Framework using Oracle Database - ORA-00942: table or view does not exist

I can't solve my problem with my local Oracle database.
I'm tryong to connect to my local Oracle database (Oracle Database 11g Express Edition)
Later on I will use JNDI to another Oracle Database, but I think this should still work.
Driver: ojdbc6.jar in /lib
db.default.driver=oracle.jdbc.driver.OracleDriver
db.default.url="jdbc:oracle:thin:#localhost:1521:xe"
db.default.user="user"
db.default.pass="pass"
So I know I do connect to the database, but the error is that it says that the table does not exist. I'm not even creating or querying to a table (no model exists - but I've tried with having a model too, same error). Something seems to be wrong in the beginning and I don't know how to Debug this.
Error:
**java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist**
oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:457)
oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:400)
oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:926)
oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:476)
oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:200)
oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:543)
oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:197)
oracle.jdbc.driver.T4CStatement.executeForDescribe(T4CStatement.java:1213)
oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1492)
oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1710)
oracle.jdbc.driver.OracleStatement.executeQuery(OracleStatement.java:2006)
oracle.jdbc.driver.OracleStatementWrapper.executeQuery(OracleStatementWrapper.java:1709)
com.jolbox.bonecp.StatementHandle.executeQuery(StatementHandle.java:503)
play.api.db.evolutions.Evolutions$.executeQuery(Evolutions.scala:118)
play.api.db.evolutions.Evolutions$.databaseEvolutions(Evolutions.scala:334)
play.api.db.evolutions.Evolutions$.evolutionScript(Evolutions.scala:306)
play.api.db.evolutions.EvolutionsPlugin$$anonfun$onStart$1$$anonfun$apply$1.apply$mcV$sp(Evolutions.scala:435)
play.api.db.evolutions.EvolutionsPlugin.withLock(Evolutions.scala:478)
play.api.db.evolutions.EvolutionsPlugin$$anonfun$onStart$1.apply(Evolutions.scala:434)
play.api.db.evolutions.EvolutionsPlugin$$anonfun$onStart$1.apply(Evolutions.scala:432)
scala.collection.immutable.List.foreach(List.scala:309)
play.api.db.evolutions.EvolutionsPlugin.onStart(Evolutions.scala:432)
play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63)
play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63)
scala.collection.immutable.List.foreach(List.scala:309)
play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:63)
play.api.Play$$anonfun$start$1.apply(Play.scala:63)
play.api.Play$$anonfun$start$1.apply(Play.scala:63)
When reading about it I've only found that I might not have permission to some table, but the thing is that I use the same login in Oracle SQL Developer and it works.
As nico_ekito wrote, you need to create this table manually.
This one works for me:
CREATE TABLE play_evolutions
(
id Number(10,0) Not Null Enable,
hash VARCHAR2(255 Byte),
applied_at Timestamp Not Null,
apply_script clob,
revert_script clob,
state Varchar2(255),
last_problem clob,
CONSTRAINT play_evolutions_pk PRIMARY KEY (id)
);
Try to manually create a play_evolutions table with the following columns (by adapting the types to the ones used by Oracle):
id int not null primary key, hash varchar(255) not null,
applied_at timestamp not null,
apply_script text,
revert_script text,
state varchar(255),
last_problem text
In conf/application.conf
Un-comment the following line:
evolutionplugin=disabled
This is if you don't need Evolutions (to track schema changes).

Resources