EF Core NOT NULL constraint failed on a nullable column - sqlite

So for some reason my migrations broke after adding a one to one relationship in the models in ASP Core, the real problematic function is
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<long>(
name: "RatingId",
table: "ContentPosts",
type: "INTEGER",
nullable: true,
defaultValue: null);
migrationBuilder.CreateTable(
name: "Ratings",
columns: table => new
{
Id = table.Column<long>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Commends = table.Column<long>(type: "INTEGER", nullable: false),
Views = table.Column<long>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Ratings", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_ContentPosts_RatingId",
table: "ContentPosts",
column: "RatingId");
migrationBuilder.AddForeignKey(
name: "FK_ContentPosts_Ratings_RatingId",
table: "ContentPosts",
column: "RatingId",
principalTable: "Ratings",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}
Where the last AddForeignKey method throws an error
SQLite Error 19: 'NOT NULL constraint failed: ef_temp_ContentPosts.RatingId'
I've also set the default value of the RatingId to be 0L and I get the error
SQLite Error 19: 'FOREIGN KEY constraint failed'
I've checked the database in DB Browser and ContentPosts still does not have the RatingId column and so it should be fine that nothing interferes with adding a new column named RatingId

Related

DynamoDB ValidationException: A value provided cannot be converted into a number

I have very strange behavior in my Nest.js application with dynamoose. This is my location schema:
import { NULL, Schema } from 'dynamoose';
export const LocationSchema = new Schema({
country: String,
city: String,
zipCode: String,
companyName: {
type: [String, NULL],
default: null,
},
streetAddress: {
type: [String, NULL],
default: null,
},
contactPhone: {
type: [String, NULL],
default: null,
},
contactEmail: {
type: [String, NULL],
default: null,
},
});
In body I'm posting this:
"deliveryLocation":{"country":"United Kingdom","zipCode":"M11 9","city":"MANCHESTER AIRPORT"},"pickupLocation":{"country":"Belgium","zipCode":"1020","city":"BRUXELLES/BRUSSEL 2"}
And I got ValidationException: A value provided cannot be converted into a number
As you can see any property has type Number.
What is even more strange if I change in deliveryLocation zipCode to M119 it is valid for DynamoDB.
If I'm changing in deliveryLocation United Kingdom to 'United Kindon' and let zipCode stay 'M11 9' the error is not coming.
If I making request with same values in deliveryLocation and pickupLocation - {"country":"United Kingdom","zipCode":"M11 9","city":"MANCHESTER AIRPORT"} - there is also no error.
To sum up error occurs only in this combination
"deliveryLocation":{"country":"United Kingdom","zipCode":"M11 9","city":"MANCHESTER AIRPORT"},"pickupLocation":{"country":"Belgium","zipCode":"1020","city":"BRUXELLES/BRUSSEL 2"}
Any idea why it is happening?
I tried adding to schema
saveUnknown: true,
but it is not solving the problem.

dynamodb add item to the array list

Using serverless-stack.
I have a table company with multiple branches:
new sst.Table(this, 'Company', {
fields: {
userId: sst.TableFieldType.STRING,
companyId: sst.TableFieldType.STRING,
companyName: sst.TableFieldType.STRING,
branches: [
{
branchId: sst.TableFieldType.STRING,
branchName: sst.TableFieldType.STRING
}
]
},
primaryIndex: {partitionKey: "userId", sortKey: "companyId"}
})
I am trying to add branch to the branches:
const branch = {
branchId: uuid.v1(),
branchName: data.branchName
}
const params = {
TableName: process.env.COMPANY_TABLE_NAME,
Key: {userId: "1", companyId: data.companyId},
UpdateExpression: "ADD #branches :branch",
ExpressionAttributeNames: { "#branches" : "branches" },
ExpressionAttributeValues: { ":branch": [branch] }
}
But I get this error:
ERROR ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: LIST, typeSet: ALLOWED_FOR_ADD_OPERAND
ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: LIST, typeSet: ALLOWED_FOR_ADD_OPERAND
ADD is only for numbers and sets. Your branches attribute is a list. So you can use SET with list_append.
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements
SET #branches = list_append(#branches, :branch) is correct. But ExpressionAttributeValues should be ExpressionAttributeValues: { ":branch": {"L":[branch]}}
You can refer to https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.update_item

Incompatible object types

/* #flow */
type optionsType = Array<{id: string | number, name: string}>;
type modelsType = Array<{id: number, name: string}>;
function getOptions(options: optionsType): string {
return options.reduce((a, e) => {
return a + `<option value="${e.id.toString()}">${e.name}</option>`;
}, '');
}
const options: modelsType = [
{id: 1, name: 'punto'},
{id: 2, name: 'duo'},
{id: 500, name: 'cinquecento'},
];
console.log(getOptions(options));
The above example complains Cannot call "getOptions" with "options" bound to "options" because number [1] is incompatible with string [2] in property "id" of array element. but in my understanding the modelsType is just more generic than the optionsType. Why does flow complain and how can I get this to work as expected?
If
let second: secondType = first;
were allowed as-is, it would mean that it's valid to do
second.id = "some-id";
but that would corrupt the type of firstType since it's the same object, and the type is number, but it's now been assigned a string.
To make this work, you need to say that secondType.id is read-only, or "covariant". You can do this by changing
type secondType = {id: string | number, name: string};
to
type secondType = {+id: string | number, name: string};
(Example on flow.org/try)
The final solution to my use case:
/* #flow */
type optionsType = $ReadOnlyArray<{+id: string | number, name: string}>;
type modelsType = Array<{id: number, name: string}>;
function getOptions(options: optionsType): string {
return options.reduce((a, e) => {
return a + `<option value="${e.id.toString()}">${e.name}</option>`;
}, '');
}
const options: modelsType = [
{id: 1, name: 'punto'},
{id: 2, name: 'duo'},
{id: 500, name: 'cinquecento'},
];
console.log(getOptions(options));

Symfony classNotFoundInNamespaces exception

I am working with a bundle called rss-atom-bundle. Through this bundle I should be able to fetch the RSS feeds and save them to the database.
I can get the bundle to work up till getting the feeds from the URL but when I try to presist I get the following error and I just cant figure it out why I am getting it.
The class 'Debril\RssAtomBundle\Protocol\Parser\Item' was not found in the chain configured namespaces Symfony\Bundle\AsseticBundle\Entity, AppBundle\Entity`
Looking online and at stackoverflow i came across questions that were related to this but all of them are talking about by default the Entity should be inside the Entity folder of the Bundle and if they are not then this error appears but my Entity files are inside Entity folder and I followed the instructions given by the bundle author but still i cant get passed this error
This is what my Controller looks like
$em = $this->getDoctrine()->getManager();
// fetch the FeedReader
$reader = $this->container->get('debril.reader');
// this date is used to fetch only the latest items
$unmodifiedSince = '01/01/2000';
$date = new \DateTime($unmodifiedSince);
// the feed you want to read
$url = 'http://example.com/feed/';
$feeds = $reader->getFeedContent($url, $date);
$items = $feeds->getItems();
dump($items);
foreach ( $items as $item ) {
$em->persist($item);
}
$em->flush();
As per bundle instructions I did implement FeedInterface to my Feed Entity and ItemInInterface, ItemOutInterface to my Item Entity
This is what my orm.yml looks like for Feed and Item Entity
Feed
AppBundle\Entity\Feed:
type: entity
table: null
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
title:
type: string
length: 255
description:
type: text
link:
type: text
publicId:
type: text
lastModified:
type: datetime
lastViewed:
type: datetime
oneToMany:
items:
targetEntity: AppBundle\Entity\Item
mappedBy: feed
cascade: ["persist"]
lifecycleCallbacks: { }
Item
AppBundle\Entity\Item:
type: entity
table: null
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
title:
type: string
length: 255
title:
type: text
nullable: true
summary:
type: text
nullable: true
description:
type: text
nullable: true
medias:
type: text
nullable: true
updated:
type: string
nullable: true
publicId:
type: string
nullable: true
link:
type: string
nullable: true
comment:
type: string
nullable: true
author:
type: string
nullable: true
manyToOne:
feed:
targetEntity: AppBundle\Entity\Feed
inversedBy: items
joinColumn:
name: feed_id
referencedColumnName: id
Any help will be really appreciated as I am clueless why i am getting the error?
Try to add RssAtomBundle to the list with mappings in app/config/config.yml
orm:
entity_managers:
default:
connection: default
mappings:
AppBundle: ~
AsseticBundle: ~
RssAtomBundle: ~

Symfony2 / Doctrine / Mapping Converter / Relationship / PK Strange Behavior

After searching for a whole while i decided to show you my problem with the mapping converter implementation in Symfony2. First, i show you my setup:
The user tables having a relationship:
-- -----------------------------------------------------
-- Table `event_manager`.`user`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `event_manager`.`user` ;
CREATE TABLE IF NOT EXISTS `event_manager`.`user` (
`id` INT NOT NULL AUTO_INCREMENT ,
`email` VARCHAR(255) NULL ,
`salt` VARCHAR(255) NULL ,
`password` VARCHAR(255) NULL ,
`logged_in` TINYINT(1) NULL ,
`status` ENUM('active', 'inactive', 'deleted') NULL ,
PRIMARY KEY (`id`) ,
CONSTRAINT `fk_user_user_data1`
FOREIGN KEY (`id` )
REFERENCES `event_manager`.`user_data` (`user_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `event_manager`.`user_data`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `event_manager`.`user_data` ;
CREATE TABLE IF NOT EXISTS `event_manager`.`user_data` (
`user_id` INT NOT NULL ,
`image_id` INT NULL ,
`gender` ENUM('male','female') NULL ,
`first_name` VARCHAR(255) NULL ,
`last_name` VARCHAR(255) NULL ,
`address` VARCHAR(255) NULL ,
`zip` VARCHAR(255) NULL ,
`city` VARCHAR(255) NULL ,
`phone_private` VARCHAR(255) NULL ,
`phone_mobile` VARCHAR(255) NULL ,
`phone_work` VARCHAR(255) NULL ,
`user_datacol` VARCHAR(45) NULL ,
PRIMARY KEY (`user_id`) ,
CONSTRAINT `fk_user_data_image1`
FOREIGN KEY (`image_id` )
REFERENCES `event_manager`.`image` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE INDEX `fk_user_data_image1_idx` ON `event_manager`.`user_data` (`image_id` ASC) ;
With that on my DB, i use the doctrine converter with this command:
php app/console doctrine:mapping:convert yml ./src/path-to-bundle/Resources/config/doctrine --from-database --force --filter=User
Then i get this result on the user YAML:
User:
type: entity
table: user
fields:
email:
type: string
length: 255
fixed: false
nullable: true
salt:
type: string
length: 255
fixed: false
nullable: true
password:
type: string
length: 255
fixed: false
nullable: true
loggedIn:
type: boolean
nullable: true
column: logged_in
status:
type: string
length: null
fixed: false
nullable: true
manyToMany:
userGroup:
targetEntity: UserGroup
cascade: { }
mappedBy: null
inversedBy: user
joinTable:
name: user_has_user_group
joinColumns:
-
name: user_id
referencedColumnName: id
inverseJoinColumns:
-
name: user_group_id
referencedColumnName: id
orderBy: null
oneToOne:
id:
targetEntity: UserData
cascade: { }
mappedBy: null
inversedBy: null
joinColumns:
id:
referencedColumnName: user_id
orphanRemoval: false
lifecycleCallbacks: { }
As you can see, doctrine removes the "id" column as primary key and uses it instead as the name for the relationship which brings me finally to entity methods like this:
/**
* Set id
*
* #param \Parella\EventManagerBundle\Entity\UserData $id
* #return User
*/
public function setId(\Parella\EventManagerBundle\Entity\UserData $id = null)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return \Parella\EventManagerBundle\Entity\UserData
*/
public function getId()
{
return $this->id;
}
This is of course totally not what i want, and i have often to create many entites at once from the database, so manually fixing this is not really an option. Unfortunately i have no idea if i'm causing the problem or doctrine. Do i miss something?
Thanks for your responses.
Copied my comment to here because I confirmed the actual problem.
Doctrine does not support a single column being both primary id as well as participating in an owning relation. Think about it. What should $user->getId() return? The id or $userData?
Add a user_data_id column to user and put the relation on it.
And I would just edit the yml files and then use doctrine:schema:drop/update to generate the tables. Let Doctrine do things it's way unless you really need to maintain control.

Resources