Seed script raise Invalid datetime format error - mysql

I moved my app from laravel 5 to 7 and running initial migration seed suffer error:
Migrating: 2018_08_09_113432_create_vote_item_users_results_table
Illuminate\Database\QueryException
SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '2020-03-29 03:03:20' for column 'created_at' at row 1 (SQL: insert into `vt2_vote_item_users_result` (`user_id`, `vote_item_id`, `is_correct`, `created_at`) values (5, 27, 0, 2020-03-29 03:03:20))
Which I did not have priorly 1-2 years working with this app.
My table is created with migration
public function up()
{
Schema::create('vote_item_users_result', function (Blueprint $table) {
$table->increments('id');
$table->integer('vote_item_id')->unsigned();
$table->foreign('vote_item_id')->references('id')->on($this->vote_items_tb)->onDelete('CASCADE');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on($this->users_tb)->onDelete('CASCADE');
$table->boolean('is_correct')->default(false);
$table->timestamp('created_at')->useCurrent();
$table->unique(['vote_item_id', 'user_id'], 'vote_item_users_result_vote_item_id_user_id_index');
$table->index(['vote_item_id', 'is_correct', 'user_id'], 'vote_item_users_result_vote_item_id_is_correct_user_id_index');
});
Artisan::call('db:seed', array('--class' => 'VoteItemUsersResultsInitData'));
}
after this migration I see next fields in vt2_vote_item_users_result table of the db :
id int(10) unsigned Auto Increment
vote_item_id int(10) unsigned
user_id int(10) unsigned
is_correct tinyint(1) [0]
created_at timestamp [CURRENT_TIMESTAMP]
and running initial seed I fill field created_at manually as I need this date to be withing some range,
not only at date of creation:
$usersList = User::all();
$votesList = Vote::all();
$faker = \Faker\Factory::create();
foreach ($usersList as $nextUser) {
foreach ($votesList as $nextVote) {
$voteItemsList = VoteItem::getByVote($nextVote->id)->orderBy('ordering', 'asc')->get();
if ( count($voteItemsList) > 0 ) {
$random_index = mt_rand(0, count($voteItemsList) - 1);
if ( ! empty($voteItemsList[$random_index]->id)) {
if ( $voteItemsList[$random_index]->is_correct and in_array($nextVote->id,[1,2]) ) continue;
if ( !$voteItemsList[$random_index]->is_correct and in_array($nextVote->id,[3,4]) ) continue;
DB::table('vote_item_users_result')->insert([
'user_id' => $nextUser->id,
'vote_item_id' => $voteItemsList[$random_index]->id,
'is_correct' => $voteItemsList[$random_index]->is_correct,
'created_at' => $faker->dateTimeThisMonth()->format('Y-m-d h:m:s'), // I fill created_at manually
]);
}
}
} // foreach ($votesList as $nextVote) {
} // foreach ($usersList as $nextUser) {
Running sql from error as :
insert into `vt2_vote_item_users_result` (`user_id`, `vote_item_id`, `is_correct`, `created_at`)
values (5, 27, 0, '2020-03-29 03:03:20')
I got error :
Error in query (1292): Incorrect datetime value: '2020-03-29 03:03:20' for column 'created_at' at row 1
I do not see why error ? The sql-statement seems valid...
Mysql 5.7.29-0ubuntu0.18.04.1
Laravel Framework 7.6.2
PHP 7.2.24-0ubuntu0.18.04.4
Thanks!

Related

Occasionally Laravel firstOrCreate results in 0 id value and results in Integrity constraint violation: 1452 Cannot add or update a child row

Job file
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
try {
$address = $this->setupCustomer();
} catch (\Exception $exception) {
throw $exception;
}
}
protected function setupCustomer(): CustomerAddress
{
$customer = Customer::firstOrCreate(
[
'email' => $this->transactionDetails['email'],
],
[
'first_name' => $this->transactionDetails['first_name'],
'last_name' => $this->transactionDetails['last_name'],
'phone' => $this->transactionDetails['phone'] ?? '',
]
);
return $customer->addAddress([
'street_address' => $this->transactionDetails['delivery_address']['address'],
'street_address2' => $this->transactionDetails['delivery_address']['address2'],
'postal_code' => $this->transactionDetails['delivery_address']['post_code'],
'city' => $this->transactionDetails['delivery_address']['city'],
'region' => $this->transactionDetails['delivery_address']['region'],
'country' => $this->transactionDetails['delivery_address']['country'],
]);
}
Customer.php Model
public function addAddress(array $address): CustomerAddress
{
$countryId = optional(Country::byCountryCode($address['country'])
->first())
->id;
$address = $this->addresses()->firstOrCreate([
'country_id' => $countryId ?? 0,
'street_address' => $address['street_address'],
'street_address2' => $address['street_address2'] ?? null,
'post_code' => $address['postal_code'],
'city' => $address['city'],
'region' => $address['region'],
]);
return $address;
}
/**
* Customer can have many addresses.
*
* #return HasMany
*/
public function addresses()
{
return $this->hasMany(CustomerAddress::class);
}
Occasionally, I get the error below:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`tbps`.`customer_addresses`, CONSTRAINT `customer_addresses_customer_id_foreign` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`)) (SQL: insert into `customer_addresses` (`country_id`, `street_address`, `street_address2`, `post_code`, `city`, `region`, `customer_id`, `updated_at`, `created_at`) values (<country_id>, <street_address>, ?, <post_code>, <city>, ?, 0, <timestamp>, <timestamp>))
Why does it end up with the customer_id = 0 in the SQL statement? The customer is always created in the database--I am unable to replicate as it occurs occasionally.
Object from Stripe
{
"payment_id": "pi_3MRiqNE7F1cRlWVXXXXXXXXX",
"currency": "gbp",
"payment_type": "card",
"email": "XXXXXXXX#gmail.com",
"name": null,
"first_name": "XXXXX",
"last_name": "XXXX",
"phone": "07XXXXXXXXX",
"purchase_dt": "2023/XX/XX XX:XX:XX",
"discount_code": null,
"delivery_address": {
"address": "<address>",
"address2": null,
"city": "<city>",
"post_code": "<post_code>",
"region": null,
"country": "<country>"
},
...
...
}
I am having this issue too! This is how we have it set up:
class ModelOne
{
public function modelTwo()
{
return $this->belongsTo(ModelTwo::class);
}
}
class ModelTwo
{
public function modelOnes()
{
return $this->hasMany(ModelOne::class);
}
}
$modelOne = ModelOne::findOrFail(1);
$modelTwo = ModelTwo::firstOrCreate([
'tenant_id' => 1,
'machine_name' = 'my_new_model_1',
], [
'name' => 'My new model',
]);
$modelOne->modelTwo()->associate($modelTwo);
Then I randomly get:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`db`.`model_one`, CONSTRAINT `model_one_model_two_id_foreign` FOREIGN KEY (`model_two_id`) REFERENCES `model_two` (`id`) ON DELETE SET NULL) (SQL: update `model_one` set `model_two_id` = 0, `model_one`.`updated_at` = ? where `id` = ?)
But I cant reproduce it locally, I just get emails from customers asking to fix it...

how to compare json value passed as sp parameter to json value stored in mysql

here is MySQL sp:
CREATE DEFINER=`root`#`localhost` PROCEDURE `records_del_record`(in p_record json)
BEGIN
select p_record;
update records set rec_status = 1 where recordObj = p_record;
END
recordObj is of type json in records table of database
here is how I am invoking query:
dbCon.query(`CALL records_del_record(?)`,[[JSON.stringify(record)]], (err, results) => {
if (err) {
console.log(err)
reject()
} else {
console.log(results[0][0].p_record)
console.log(results[1])
resolve()
}
})
output :
{ from: 'first', recTime: '2022-08-31 19:12:56.000000', 'next visit': '', prescription: 'Mobile 2' } ResultSetHeader { fieldCount: 0, affectedRows: 0, insertId: 0, info: '', serverStatus: 34, warningStatus: 0 }
when sp is executed it doesn't change any rows...
I suspect there is mismatch of type while comparing p_record and recordObj.
any help is appreciated...

updateOnDuplicate not effect

hello i want insert data with bulkCreate ex:
[
{
"typeId": 5,
"devEui": "0094E796CBFCFEF9",
"application_name": "Pressure No.10",
"createdAt": "2020-02-05T08:07:17.000Z",
"updatedAt": "2020-02-05T08:07:17.000Z"
}
]
and my sequelize code :
return models.sequelize.transaction(t=>{
return models.iot_nodes.bulkCreate(data,{
updateOnDuplicate: ["devEui",]
})
})
when i hit this code in first data that will be insert to db
my problem is when i hit again whit same data that not update, just insert in new row
iam using mysql db, laragon
log:
Executing (f202b84c-c5d8-4c67-954c-e22f96fb93d8): START TRANSACTION;
Executing (default): INSERT INTO `iot_nodes` (`id`,`typeId`,`devEui`,`application_name`,`createdAt`,`updatedAt`) VALUES (NULL,5,'0094E796CBFCFEF9','Pressure No.10','2020-02-05 08:07:17','2020-02-05 08:07:17') ON DUPLICATE KEY UPDATE `id`=VALUES(`id`),`devEui`=VALUES(`devEui`);
Executing (f202b84c-c5d8-4c67-954c-e22f96fb93d8): COMMIT;
It seems to fit this scenario based on the information. You want to update devEui field. updateOnDuplicate option:
Fields to update if row key already exists (on duplicate key update)?
So, the row key already exists means the table must have a unique key or the primary key is duplicated when you insert the data.
E.g.
import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';
class IotNode extends Model {}
IotNode.init(
{
typeId: {
type: DataTypes.INTEGER,
unique: true,
},
devEui: DataTypes.STRING,
application_name: DataTypes.STRING,
},
{ sequelize, modelName: 'iot_nodes' },
);
(async function test() {
try {
await sequelize.sync({ force: true });
const datas = [
{
typeId: 5,
devEui: '0094E796CBFCFEF9',
application_name: 'Pressure No.10',
createdAt: '2020-02-05T08:07:17.000Z',
updatedAt: '2020-02-05T08:07:17.000Z',
},
];
await IotNode.bulkCreate(datas, { updateOnDuplicate: ['devEui'] });
await IotNode.bulkCreate(datas, { updateOnDuplicate: ['devEui'] });
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
As you can see, I make the typeId unique and execute IotNode.bulkCreate twice. The generated SQL logs:
Executing (default): INSERT INTO "iot_nodes" ("id","typeId","devEui","application_name") VALUES (DEFAULT,5,'0094E796CBFCFEF9','Pressure No.10') ON CONFLICT ("typeId") DO UPDATE SET "devEui"=EXCLUDED."devEui" RETURNING *;
Executing (default): INSERT INTO "iot_nodes" ("id","typeId","devEui","application_name") VALUES (DEFAULT,5,'0094E796CBFCFEF9','Pressure No.10') ON CONFLICT ("typeId") DO UPDATE SET "devEui"=EXCLUDED."devEui" RETURNING *;
sequelize use the unique typeId field as the duplicate key. Check the rows in the database:
=# select * from iot_nodes;
id | typeId | devEui | application_name
----+--------+------------------+------------------
1 | 5 | 0094E796CBFCFEF9 | Pressure No.10
(1 row)
The data row is upserted as expected.
If we remove the unique: true from typeId field. sequelize will use primary key as the duplicate key. Take a look below generated SQL and data rows in the database:
Executing (default): INSERT INTO "iot_nodes" ("id","typeId","devEui","application_name") VALUES (DEFAULT,5,'0094E796CBFCFEF9','Pressure No.10') ON CONFLICT ("id") DO UPDATE SET "devEui"=EXCLUDED."devEui" RETURNING *;
Executing (default): INSERT INTO "iot_nodes" ("id","typeId","devEui","application_name") VALUES (DEFAULT,5,'0094E796CBFCFEF9','Pressure No.10') ON CONFLICT ("id") DO UPDATE SET "devEui"=EXCLUDED."devEui" RETURNING *;
=# select * from iot_nodes;
id | typeId | devEui | application_name
----+--------+------------------+------------------
1 | 5 | 0094E796CBFCFEF9 | Pressure No.10
2 | 5 | 0094E796CBFCFEF9 | Pressure No.10
(2 rows)

Sequelize Upsert is Creating instead of Updating

According to the documentation found here it states as follows
upsert(values, [options]) -> Promise.<created>
Insert or update a single row. An update will be executed if a row which matches the supplied values on either the primary key or a unique key is found. Note that the unique index must be defined in your sequelize model and not just in the table. Otherwise you may experience a unique constraint violation, because sequelize fails to identify the row that should be updated.
So my expectation is that upserting using a unique key should replace the existing value. However when my code runs instead of updating the existing database record, it adds a new one. What am I doing wrong?
here is a sample of my model
'use strict'
module.exports = (db, dataTypes) => {
const titanJob = db.define('titanJob', {
titanId: {
type: dataTypes.STRING,
allowNull: false,
unique: true
},
name: {
type: dataTypes.STRING,
allowNull: false
}
}, {
timestamps: true
})
return titanJob
}
and here is an example of my upsert
await asyncForEach(res.data.hits.hits, async es => {
const src = es._source
try {
await titanJob.upsert({
name: src.name,
titanId: src.id,
}, { titanId: src.id })
logger.debug(`[${file}] upsert successful`)
} catch (err) {
logger.warn(`[${file}] failed to save to database`)
logger.warn(`[${file}] ${err}`)
}
})
First you should add a unique index (constraint) to your table. The data you upserting should contain the field set of the unique index (constraint).
It should work. Here is an example using "sequelize": "^5.21.3":
index.ts:
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../../db';
import assert from 'assert';
class TitanJob extends Model {}
TitanJob.init(
{
titanId: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
},
{ sequelize, modelName: 'titanJob', timestamps: true },
);
(async function test() {
try {
await sequelize.sync({ force: true });
const datas = [
{ titanId: '1', name: 'programmer' },
{ titanId: '2', name: 'teacher' },
];
const jobs = await TitanJob.bulkCreate(datas);
assert.deepEqual(
jobs.map((job) => ({ titanId: job.id, name: job.name })),
datas,
'Should bulk create programmer and teacher datas',
);
const rval = await TitanJob.upsert({ titanId: '1', name: 'driver' }, { returning: true });
assert.equal(rval[0].titanId, '1', 'Should update the row which titanId is "1"');
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
Execution results:
{ POSTGRES_HOST: '127.0.0.1',
POSTGRES_PORT: '5430',
POSTGRES_PASSWORD: 'testpass',
POSTGRES_USER: 'testuser',
POSTGRES_DB: 'node-sequelize-examples' }
Executing (default): DROP TABLE IF EXISTS "titanJob" CASCADE;
Executing (default): DROP TABLE IF EXISTS "titanJob" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "titanJob" ("id" SERIAL , "titanId" VARCHAR(255) NOT NULL UNIQUE, "name" VARCHAR(255) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'titanJob' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "titanJob" ("id","titanId","name","createdAt","updatedAt") VALUES (DEFAULT,'1','programmer','2020-02-14 08:09:45.506 +00:00','2020-02-14 08:09:45.506 +00:00'),(DEFAULT,'2','teacher','2020-02-14 08:09:45.506 +00:00','2020-02-14 08:09:45.506 +00:00') RETURNING *;
Executing (default): CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert(OUT created boolean, OUT primary_key text) AS $func$ BEGIN INSERT INTO "titanJob" ("titanId","name","createdAt","updatedAt") VALUES ('1','driver','2020-02-14 08:09:45.524 +00:00','2020-02-14 08:09:45.524 +00:00') RETURNING "id" INTO primary_key; created := true; EXCEPTION WHEN unique_violation THEN UPDATE "titanJob" SET "titanId"='1',"name"='driver',"updatedAt"='2020-02-14 08:09:45.524 +00:00' WHERE ("id" IS NULL OR "titanId" = '1') RETURNING "id" INTO primary_key; created := false; END; $func$ LANGUAGE plpgsql; SELECT * FROM pg_temp.sequelize_upsert();
Executing (default): SELECT "id", "titanId", "name", "createdAt", "updatedAt" FROM "titanJob" AS "titanJob" WHERE "titanJob"."id" = '1';
No assertion fails. It works as expected. Check the data rows in the database:
node-sequelize-examples=# select * from "titanJob";
id | titanId | name | createdAt | updatedAt
----+---------+---------+----------------------------+----------------------------
2 | 2 | teacher | 2020-02-14 08:09:45.506+00 | 2020-02-14 08:09:45.506+00
1 | 1 | driver | 2020-02-14 08:09:45.506+00 | 2020-02-14 08:09:45.524+00
(2 rows)
source code: https://github.com/mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/59686743

Not getting right alias name with Cakephp

I am new on CakePHP and facing a problem with SQL Alias.
I want to make an Excel file to generate a report from the MySQL database.
/**
* Generate transaction report
*
* #param none
*
* #return void
*/
public function generateReport()
{
//Getting data from the database to generate the report in Excel file
$data = $this->AchTransaction->find('all', array(
//'conditions' => $searchCondition,
'fields' => array(
"payee_name AS PAYEENAME",
'reference AS REFERENCE',
'reference2 AS REFERENCE2',
'currency AS CURRENCY',
'amount AS PAYOUTAMOUNT',
'bank_name AS BANKNAME',
'bank_branch_name AS BANKBRANCHNAME',
'bank_address AS BANKADDRESS',
'bank_country AS BANKCOUNTRY',
'account_name AS ACCOUNTNAME',
'account_class AS ACCOUNTCLASS',
'account_type AS ACCOUNTTYPE',
'bank_routing_number AS BANKROUTING',
'account_number AS ACCOUNT',
'beneficiary_address AS BENEFICIARYADDRESS',
'beneficiary_city AS BENEFICIARYCITY',
'beneficiary_state AS BENEFICIARYSTATE',
'beneficiary_postcode AS BENEFICIARYZIPCODE',
'beneficiary_country AS BENEFICIARYCOUNTRY',
'note as NOTE'
),
'order' => array('AchTransaction.id DESC')
));
// Generating Excel file
$this->Common->generateReport($data);
}
I am able to generate the Excel but having only one problem in alias, As you can see
"payee_name AS PAYEENAME",
Here the payee_name is the name of column or field in MySQL table, and I want this as PAYEE NAME, but when I write:
"payee_name AS PAYEE NAME",
I am getting this MySQL error:
Database Error
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'payee_name AS PAYEE NAME' in 'field list'
SQL Query: SELECT `payee_name AS PAYEE NAME`, `reference` AS `REFERENCE`, `reference2` AS `REFERENCE2`, `currency` AS `CURRENCY`, `amount` AS `PAYOUTAMOUNT`, `bank_name` AS `BANKNAME`, `bank_branch_name` AS `BANKBRANCHNAME`, `bank_address` AS `BANKADDRESS`, `bank_country` AS `BANKCOUNTRY`, `account_name` AS `ACCOUNTNAME`, `account_class` AS `ACCOUNTCLASS`, `account_type` AS `ACCOUNTTYPE`, `bank_routing_number` AS `BANKROUTING`, `account_number` AS `ACCOUNT`, `beneficiary_address` AS `BENEFICIARYADDRESS`, `beneficiary_city` AS `BENEFICIARYCITY`, `beneficiary_state` AS `BENEFICIARYSTATE`, `beneficiary_postcode` AS `BENEFICIARYZIPCODE`, `beneficiary_country` AS `BENEFICIARYCOUNTRY`, `note` AS `NOTE` FROM `aramor_payments`.`ach_transactions` AS `AchTransaction` WHERE 1 = 1 ORDER BY `AchTransaction`.`id` DESC
Notice: If you want to customize this error message, create app\View\Errors\pdo_error.ctp
Stack Trace
CORE\Cake\Model\Datasource\DboSource.php line 461 → PDOStatement->execute(array)
CORE\Cake\Model\Datasource\DboSource.php line 427 → DboSource->_execute(string, array)
CORE\Cake\Model\Datasource\DboSource.php line 671 → DboSource->execute(string, array, array)
CORE\Cake\Model\Datasource\DboSource.php line 1082 → DboSource->fetchAll(string, boolean)
CORE\Cake\Model\Model.php line 2631 → DboSource->read(AchTransaction, array)
APP\Controller\AchtransactionsController.php line 353 → Model->find(string, array)
[internal function] → AchtransactionsController->generateReport()
CORE\Cake\Controller\Controller.php line 485 → ReflectionMethod->invokeArgs(AchtransactionsController, array)
CORE\Cake\Routing\Dispatcher.php line 186 → Controller->invokeAction(CakeRequest)
CORE\Cake\Routing\Dispatcher.php line 161 → Dispatcher->_invoke(AchtransactionsController, CakeRequest, CakeResponse)
APP\webroot\index.php line 92 → Dispatcher->dispatch(CakeRequest, CakeResponse)
Can you please help me to get the name of payee_name field as PAYEE NAME?
Change
"payee_name AS PAYEE NAME",
to
"`payee_name` AS `PAYEE NAME`"
Another option is using virtualFields
$this->AchTransaction->virtualFields['PAYEE NAME'] = 'payee_name';
array('fields' => array('PAYEE NAME', 'etc'))