PySpark, order of column on write to MySQL with JDBC - mysql

I'm struggling a bit understanding spark and writing dataframes to a mysql database. I have the following code:
forecastDict = {'uuid': u'8df34d5a-ce02-4d02-b282-e10363690122', 'created_at': datetime.datetime(2014, 12, 31, 23, 0)}
forecastFrame = sqlContext.createDataFrame([forecastDict])
forecastFrame.write.jdbc(url="jdbc:mysql://example.com/example_db?user=bla&password=blabal123", table="example_table", mode="append")
The last line in the code throws the following error:
Incorrect datetime value: '8df34d5a-ce02-4d02-b282-e10363690122' for column 'created_at' at row 1
I can post the entire stack trace if necessary, but basically what's happening here is that the pyspark is mapping the uuid field to the wrong column in mysql. Here's the mysql definition:
mysql> show create table example_table;
...
CREATE TABLE `example_table` (
`uuid` varchar(36) NOT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
...
If we change the mysql definition to the following (notice that only the order of the columns is different):
CREATE TABLE `example_table` (
`created_at` datetime NOT NULL,
`uuid` varchar(36) NOT NULL,
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The insert works fine. Is there a way to implement this without being dependent on the order of the columns, or what's the preferred way of saving data to an external relational database from spark?
Thanks!
--chris

I would simply force expected order on write:
url = ...
table = ...
columns = (sqlContext.read.format('jdbc')
.options(url=url, dbtable=table)
.load()
.columns())
forecastFrame.select(*columns).write.jdbc(url=url, dbtable=table, mode='append')
Also be careful with using schema inference on dictionaries. This is not only deprecated but also rather unstable.

Related

While Insert Records To MySQL, get in Error Code 1054

I'm new to MySQL & I try to enter records to mysql table. I'm getting following error
INSERT INTO advertising.discountauthorizationrequst SET DARDateTime=cast('2003-01-13 16:50:32' as datetime), `DARPubCode`=trim('DD'), `DARPubDate`=cast('2022-05-08' as date), `DARAutUser`=trim("U0001"), `DARDeviceID`=trim('123456789ABCDEFGHIJKL987456'), `DARMessage`=trim("This Is Test Message"), `DARGranted`=("0"), `DARUser`=trim("DATAENTRYUSERNAME") Error Code: 1054. Unknown column 'DARDateTime' in 'field list'
I listed my INSERT statement below. Someone please help me to solve this issue. I'm using mysql workbench 8.0.
Columns:
DARDateTime datetime PK
DARPubCode varchar(3) PK
DARPubDate date PK
DARAutUser varchar(5)
DARDeviceID varchar(50)
DARMessage varchar(100)
DARGranted varchar(1)
DARUser varchar(50) PK
Here is script
INSERT INTO `advertising`.`discountauthorizationrequst`
SET
`DARDateTime`=cast('2003-01-13 16:50:32' as datetime),
`DARPubCode`=trim('DD'),
`DARPubDate`=cast('2022-05-08' as date),
`DARAutUser`=trim("U0001"),
`DARDeviceID`=trim('123456789ABCDEFGHIJKL987456'),
`DARMessage`=trim("This Is Test Message"),
`DARGranted`=("0"),
`DARUser`=trim("DATAENTRYUSERNAME");
Edited..
Table Inspactor - DDL
CREATE TABLE `discountauthorizationrequst` (
`DARDateTime` datetime NOT NULL,
`DARPubCode` varchar(3) NOT NULL,
`DARPubDate` date NOT NULL,
`DARAutUser` varchar(5) DEFAULT NULL,
`DARDeviceID` varchar(50) DEFAULT NULL,
`DARMessage` varchar(100) DEFAULT NULL,
`DARGranted` varchar(1) DEFAULT NULL,
`DARUser` varchar(50) NOT NULL,
PRIMARY KEY (`DARDateTime`,`DARPubCode`,`DARPubDate`,`DARUser`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
You are actually confusing the SQL commands and coming up with a hybrid of them. The INSERT command most commonly is done in two ways..
insert into SomeTable
( these, columns )
values
( oneValue, anotherValue)
or
insert into SomeTable( these, columns )
select oneColumn, secondColumn
from SomeOtherTable
where SomeCondition
The UPDATE command is based on an EXISTING record that you want to change
Update SomeTable set
thisColumn = SomeValue,
anotherColumn = SomeOtherValue
where SomeCondition
So, what you appear to be doing would be written as
INSERT INTO advertising.discountauthorizationrequst
( DARDateTime,
DARPubCode,
DARPubDate,
DARAutUser,
DARDeviceID,
DARMessage,
DARGranted,
DARUser
)
values
(
cast('2003-01-13 16:50:32' as datetime),
'DD',
'2022-05-08',
'U0001',
'123456789ABCDEFGHIJKL987456',
'This Is Test Message',
'0',
'DATAENTRYUSERNAME'
)
Notice the readability with formatting, you can see each column that is needed followed by the explicit values (which could be parameterized during code later) are in the same ordinal context. So, if you ever needed to add a new column to the insert, easy to do with the same ordinal position in the values provided secondarily to it.
As for the 3rd column, by providing a string in YYYY-MM-DD, SQL typically auto-converts to a date format. Other fields, you dont need to explicitly TRIM() everything. If parameterized, you would pass the trimmed VALUE, when you get to that point in your development.
I found the mistake that I made. I created triggers for the above table. After I deleted those triggers its working.

Changing column type from MEDIUMTEXT to JSON causes Cannot CAST value to JSON error on insert and update

I'm using AWS Aurora MySQL 5.7. I have a column that is of type MEDIUMTEXT that I'd like to convert to JSON. After using an ALTER to accomplish this, I can neither update the newly JSON-typed field of an existing record nor insert new records. In both cases, a Cannot CAST value to JSON error is thrown. the default character set for this database is latin1, but the character set on this table is utf8.
The table is defined like:
CREATE TABLE `table_sample` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`config` mediumtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT
I've tried changing the column type via:
ALTER TABLE table_sample
ADD COLUMN config2 JSON DEFAULT NULL;
UPDATE table_sample
SET config2 = IF(JSON_VALID(config), config, NULL);
ALTER TABLE table_sample
DROP COLUMN config;
ALTER TABLE table_sample
CHANGE config2 config JSON;
Attempting to duplicate a record like this, after the conversion to JSON, is one way to cause the aforementioned CAST error:
INSERT INTO table_sample (config)
SELECT config FROM table_sample WHERE id = 1;

ERROR 1265 (01000): Data truncated for column

Hello i am a student and not familiar with MySQL.
I am new in mysql and i need help!
I have a database and have some troubles inserting data into one table.
The table name is makina
CREATE TABLE `makina` (
`lloji` varchar(20) DEFAULT NULL,
`vitprodhimi` int(9) DEFAULT NULL,
`ngjyra` enum('bardhe','blu','kuqe','zeze') DEFAULT 'bardhe'
) ENGINE=InnoDB DEFAULT CHARSET=latin1
And for the column ngjyra i doesn't accept the value red.
The error is because of ENUM data type, it accept only your specific values.
Read more on : https://dev.mysql.com/doc/refman/8.0/en/enum.html
If you want to accept more values you should alter your table : How do I add more members to my ENUM-type column in MySQL?
ALTER TABLE
`makina`
MODIFY COLUMN
`ngjyra` enum(
'existing_value1',
'existing_value2',
'existing_value3',
'existing_value4',
'new_value1',
'new_value2'
)
DEFAULT `bardhe`;

Error while converting mysql to sqlite

I have a perl script that converts Mysql dump to sqlite using the module 'SQL::Translator'.
Mysql file have following:
CREATE TABLE `table1` (
`id1` char(4) NOT NULL,
`text1` char(2) NOT NULL,
`text2` char(2) NOT NULL,
`text3` enum('N','Y') NOT NULL,
UNIQUE KEY `id1` (`id1`,`text1`,`text2`),
CONSTRAINT `table1_ibfk_1` FOREIGN KEY (`id1`) REFERENCES `table2` (`id1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
While converting it to final sql using 'SQL::Translator' module, I am getting following line in final sql:
CREATE INDEX "table1" ON "table2" ("table1");
when converting this final sql file to sqlite using sqlite3 command, I am getting following error.
there is already an index named table1 Error: near line 540: no such
table: main.table1
I have tried to remove the line 'CREATE INDEX "table1" ON "table2" ("table1");' from final sql, then it worked fine.
PLease help
Unlike MySQL, SQLite uses the same namespace for tables and indexes — you cannot have an index with the same name as a table. You'll need to change the name of the index.

Second timestamp column has an invalid default value

If i execute my sql create table statement i get an errormessage that says:
Invalid default value for 'end'
CREATE TABLE IF NOT EXISTS `monkeybutler`.`Setuptimeslot` (
`id` INT NOT NULL,
`begin` TIMESTAMP NOT NULL,
`end` TIMESTAMP NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
If I change the statement and comment out the "end"-column it works, but as soon as i try to create 2 columns of type TIMESTAMP it doesnt work anymore. How can I insert both columns without getting an error?
(This is the complete Create Table Statement and my mysql Version is 5.6.19)