TypeORM not setting NULL as DateString - postgresql

I have the follwing property in my Customer entity (using a Postgres DB):
#Column({
type: "timestamptz",
nullable: true
})
#IsDateString()
cancelationDate: Date | string;
I want to be able to change the date (which works) but also to set it null (which does not work)
Works:
customer.cancelationDate = moment().add({years:100}).toISOString();
Throws error:
customer.cancelationDate = null;
It says property cancelationDate has failed the following constraints: isDateString
Is there any way to update this with null? Removing the #IsDateString() results in not updating the column at all.
Any hint is highly appreciated

Related

Cannot set values on uuid or enum fields in Postgres using TypeORM

I've been stuck on this for a good hour, and unfortunately can't find anything relevant in the docs.
I'm unable to set values on fields that use types like enum or uuid. For instance:
export enum PhotoStatus {
WORKING = 'WORKING',
DONE = 'DONE'
}
export class Photo {
#PrimaryGeneratedColumn()
id: number:
#Column()
size: string;
#Column({
type: 'enum',
enum: PhotoStatus,
default: PhotoStatus.WORKING,
})
status: PhotoStatus;
}
But when I try to create a new record, like so:
const photo = new Photo();
photo.size = 'huge';
photo.status = PhotoStatus.DONE;
await connection.manager.save(photo);
It throws an error:
BadRequestException: ERROR: column "status" is of type content_status_enum but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
This happens for uuid columns too.

"QueryFailedError: invalid input syntax for integer:" when querying on type float

When querying the database using the TypeORM QueryBuilder() I get:
QueryFailedError: invalid input syntax for integer: "X"
With X being the value stored in the DB.
Originally my entity was of type;
{type: 'decimal', precision: 5, scale: 2 }
value: number
Since I have changed it to:
{type: 'real'}
value: string
and tried:
'float'
value: string
All three types throw the same error. However, if the value in the DB doesn't have any decimal places - it works fine.
I am running Postgres v11.4, TypeORM v0.2.18 and Nest.js v6.5.3
The entity definition:
export class Entity extends BaseEntity {
#Column('float')
value: string;
}
The query:
const current = await this.entityRepo
.createQueryBuilder('uL')
.leftJoin('uL.user', 'user')
.leftJoinAndSelect('uL.currentLevel', 'cL')
.where('user.id = :id', { id: userId })
.getOne();
I am expecting the entity to be returned with the value being of correct decimal spacing.
I faced the same error, after updating to TypeORM v0.2.18: PostgreSQL doesn't actually know "number"; more on that in the typeorm repository on Microsoft GitHub
Changed this:
#Column()
value: number;
... to that:
#Column({type: 'real'})
value: string;
I forgot to migrate; did you?
Important Run a migration, to actually apply these changes:
npm run typeorm:migrate ChangedNumbersTypeToReal
npm run build; npm run typeorm:run
Everything should be well now.
You can read more about migrations with TypeORM on their GitHub

How to add not null constraint in seqeulize if records with null already exist?

I had a table.
I added a new column.
Even though I had set default value in sequelize model, those columns still ended up empty.
So I get error Unhandled rejection SequelizeDatabaseError: column "col_name" contains null values
How do you populate new column with default values upon creation so not null constraint is not broken.
You can update the values first:
update t
set col_name = ?
where col_name is null;
Then add the not null constraint.
Even though I had set default value in sequelize model
I suspect there is a discrepancy between the migration and model. To insert the column with a migration containing a default value use defaultValue in your migration.
The following is a working example:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn('tests', 'new_column', {
defaultValue: 'test',
type: Sequelize.STRING
})
}
}
Before running sequelize db:migrate
After sequelize db:migrate:
The documentation for the options object in addColumn is hard to find, it's listed for a different method

Grails with MongoDB not saving null value

This is a customer domain class in Grails(v3.1):
class Customer {
static mapWith = 'mongo'
String id
String email
Boolean blacklisted
String name
String telephone
Date dateCreated
Date lastUpdated
String language = 'en'
static constraints = {
email nullable: false
blacklisted nullable: false
name nullable: true
language nullable: true
telephone nullable: true
}
static mapping = {
version false
}
}
I can insert and update into the Customer collection in MongoDB using this class, and it is working fine. The issue occurs when I try to save one of the fields with null value.
customer.telephone = null
customer.save()
Setting a value to null has no effect in the field in MongoDB collection, its value will remain set to the value before the update. For example, if the telephone is set to "1234567" and when I update it to null, the value in MongoDB remains "1234567".
I have tried using failOnError: true and flush: true in save(), both are not working. Any suggestions?
You could try using the mongo driver directly to see if it is a mongo issue or a Gorm issue.
Customer.collection.updateOne([_id:'the-id'],[telephone:null])

How to avoid DROP DEFAULT statements with Doctrine 2 Migrations diff on first run?

I had an existing PostgreSQL database with a table created like this:
CREATE TABLE product (id SERIAL PRIMARY KEY, name VARCHAR(100) DEFAULT NULL)
This table is described in a YML Doctrine2 file within a Symfony2 project:
Acme\DemoBundle\Entity\Product:
type: entity
table: product
fields:
id:
id: true
type: integer
nullable: false
generator:
strategy: SEQUENCE
name:
type: string
length: 100
nullable: true
When I run for the first time the Doctrine Migrations diff task, I should get a versioning file with no data in the up and down methods. But what I get instead is this :
// ...
class Version20120807125808 extends AbstractMigration
{
public function up(Schema $schema)
{
// this up() migration is autogenerated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != "postgresql");
$this->addSql("ALTER TABLE product ALTER id DROP DEFAULT");
}
public function down(Schema $schema)
{
// this down() migration is autogenerated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != "postgresql");
$this->addSql("CREATE SEQUENCE product_id_seq");
$this->addSql("SELECT setval('product_id_seq', (SELECT MAX(id) FROM product))");
$this->addSql("ALTER TABLE product ALTER id SET DEFAULT nextval('product_id_seq')");
}
}
Why are differences detected? How can I avoid this? I tried several sequence strategies with no success.
A little update on this question.
Using Doctrine 2.4, the solution is to use the IDENTITY generator strategy :
Acme\DemoBundle\Entity\Product:
type: entity
table: product
id:
type: integer
generator:
strategy: IDENTITY
fields:
name:
type: string
length: 100
nullable: true
To avoid DROP DEFAULT on fields that have a default value in the database, the default option on the field is the way to go. Of course this can be done with lifecycle callbacks, but it's necessary to keep the default value in the database if this database is used by other apps.
For a "DEFAULT NOW()" like default value, the solution is the following one:
Acme\DemoBundle\Entity\Product:
type: entity
table: product
id:
type: integer
generator:
strategy: IDENTITY
fields:
creation_date:
type: datetime
nullable: false
options:
default: CURRENT_TIMESTAMP
Doctrine 2.0 does not support the SQL DEFAULT keyword, and will always try to drop a postgres default value.
I have found no solution to this problem, I just let doctrine handle the sequences itself.
This is a opened bug registered here :
http://www.doctrine-project.org/jira/browse/DBAL-903