How to insert 'NULL' values for 'int' column tupes in Aurora PostgreSQL db using Python boto3 client - postgresql

I have a CSV file (MS SQL server table export) and I would like to import it to Aurora Serverless PostgreSQL database table. I did a basic preprocessing of the CSV file to replace all of the NULL values in it (i.e. '') to "NULL". The file looks like that:
CSV file:
ID,DRAW_WORKS
10000002,NULL
10000005,NULL
10000004,FLEXRIG3
10000003,FLEXRIG3
The PostgreSQL table has the following schema:
CREATE TABLE T_RIG_ACTIVITY_STATUS_DATE (
ID varchar(20) NOT NULL,
DRAW_WORKS_RATING int NULL
)
The code I am using to read and insert the CSV file is the following:
import boto3
import csv
rds_client = boto3.client('rds-data')
...
def batch_execute_statement(sql, sql_parameter_sets, transaction_id=None):
parameters = {
'secretArn': db_credentials_secrets_store_arn,
'database': database_name,
'resourceArn': db_cluster_arn,
'sql': sql,
'parameterSets': sql_parameter_sets
}
if transaction_id is not None:
parameters['transactionId'] = transaction_id
response = rds_client.batch_execute_statement(**parameters)
return response
transaction = rds_client.begin_transaction(
secretArn=db_credentials_secrets_store_arn,
resourceArn=db_cluster_arn,
database=database_name)
sql = 'INSERT INTO T_RIG_ACTIVITY_STATUS_DATE VALUES (:ID, :DRAW_WORKS);'
parameter_set = []
with open('test.csv', 'r') as file:
reader = csv.DictReader(file, delimiter=',')
for row in reader:
entry = [
{'name': 'ID','value': {'stringValue': row['RIG_ID']}},
{'name': 'DRAW_WORKS', 'value': {'longValue': row['DRAW_WORKS']}}
]
parameter_set.append(entry)
response = batch_execute_statement(
sql, parameter_set, transaction['transactionId'])
However, there is an error that gets returned suggests that there is a type mismatch:
Invalid type for parameter parameterSets[0][5].value.longValue,
value: NULL, type: <class 'str'>, valid types: <class 'int'>"
Is there a way to configure Aurora to accept NULL values for types such as int?

Reading the boto3 documentation more carefully I found that we can use isNull value set to True in case a field is NULL. The bellow code snippet shows how to insert null value to the database:
...
entry = [
{'name': 'ID','value': {'stringValue': row['ID']}}
]
if row['DRAW_WORKS'] == 'NULL':
entry.append({'name': 'DRAW_WORKS', 'value': {'isNull': True}})
else:
entry.append({'name': 'DRAW_WORKS_RATING', 'value': {'longValue': int(row['DRAW_WORKS'])}})
parameter_set.append(entry)

Related

Laravel 8 Eloquent migration generated error " 1068 Multiple primary key defined"

I have the following migration file:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateHeadersTable extends Migration
{
public function up()
{
Schema::create('headers', function (Blueprint $table) {
$table->increments('entry')->unsigned();
$table->string('id',16);
$table->string('address',256);
$table->string('desciption',512)->nullable()->default('NULL');
$table->tinyInteger('currency',)->default('0');
$table->decimal('sum',13,4);
$table->datetime('entered');
$table->tinyInteger('aborted',)->default('0');
$table->primary('entry');
});
}
public function down()
{
Schema::dropIfExists('headers');
}
}
This file was automatically generated by an online tool from a SQL file. However, when I ran "php artisan migrate," I got the following error:
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'headers'
already exists (SQL: create table `headers` (`entry` int unsigned not null
auto_increment primary key, `id` varchar(16) not null, `address`
varchar(256) not null, `desciption` varchar(512) null default 'NULL',
`currency` tinyint not null default '0', `sum` decimal(13, 4) not null,
`entered` datetime not null, `aborted` tinyint not null default '0')
default character set utf8mb4 collate 'utf8mb4_unicode_ci')
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:712
708▕ // If an exception occurs when attempting to run a query, we'll format the error
709▕ // message to include the bindings with SQL, which will make this exception a
710▕ // lot more helpful to the developer instead of just the database's errors.
711▕ catch (Exception $e) {
➜ 712▕ throw new QueryException(
713▕ $query, $this->prepareBindings($bindings), $e
714▕ );
715▕ }
716▕ }
+9 vendor frames
10 database/migrations/2023_01_31_1675138133_create_headers_table.php:23
Illuminate\Support\Facades\Facade::__callStatic()
+22 vendor frames
33 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
I am not familiar with Laravel migration files. How can I fix this? Many thanks!
Do not drop the table manually. use php artisan migrate:rollback
and then re-try php artisan migrate
Error you got states that Table 'headers' already exists in database if you have deleted table from database just check their may be entry in migrations table in database just delete it and run migration again

DB2 select JSON_ARRAYAGG

Using of JSON_ARRAYAGG does not working for me
1) [Code: -104, SQL State: 42601] An unexpected token "ORDER" was found following "CITY)
". Expected tokens may include: ")".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.28.11
2) [Code: -727, SQL State: 56098] An error occurred during implicit system action type "2". Information returned for the error includes SQLCODE "-104", SQLSTATE "42601" and message tokens "ORDER|CITY)
|)".. SQLCODE=-727, SQLSTATE=56098, DRIVER=4.28.11
I want an output like this
{"id":901, "name": "Hansi", "addresses" :
[
{ "address":"A", "city":"B"},
{ "address":"C", "city":"D"}
]
}
I am using IBM DB2 11.1 for Linux, UNIX and Windows.
values (
json_array(
select json_object ('ID' value ID,
'NAME' value NAME,
'ADDRESSES' VALUE JSON_ARRAYAGG(
JSON_OBJECT('ADDRESS' VALUE ADDRESS,
'CITY' VALUE CITY)
ORDER BY ADDRESS)
)
FROM CUSTOMER
JOIN CUSTOMER_ADDRESS ON ADDRESS_CUSTOMER_ID = ID
GROUP BY ID, NAME
FORMAT JSON
));
Used tables are:
CUSTOMER - ID (INT), NAME (VARCHAR64)
ADDRESS - ADDRESS (VARCHAR64), CITY (VARCHAR64)

Column names return lowercase in aws glue

I am new to AWS Glue, and have created job through crawler which point the source target CSV-file in S3-bucket.
The CSV-file contains following columns as:
userId jobTitleName firstName lastName preferredFullName employeeCode region
Now during the job execution, it throws following error
Key error: userid' not exist. As notified, the issue looks the case sensitive issue. so as per the glue-document, I created mapping for the schema
mappingsSchema=[('userid', 'integer', 'userId', 'integer'),
('jobtitlename', 'string', 'jobTitleName', 'string'),
('firstname', 'string', 'firstName', 'string'),
('lastname', 'string', 'lastName', 'string'),
('preferredfullName', 'string', 'preferredFullname', 'string'),
('employeecode', 'string', 'employeeCode', 'string'),
('region', 'string','region', 'string')]
mapped_dynamic_frame_read=dynamic_frame_read.apply_mapping(mappings = mappingsSchema, case_sensitive = True, transformation_ctx = "tfx")
##And converting to the spark df
df = mapped_dynamic_frame_read.toDF()
Still I'mm getting the same mentioned error.
How can resolve this kind of issue?
Hi #Emerson The issue was with mappings in which column names were wrongly specified against the schema definition. Now it's fixed and working fine.. Thanks

Problem with PostgreSQL json object (PGobject) to logstash - type cast problem

I am trying to index data from a PostgreSQL database to elastic search using logstash. I have a column in the database which is of type JSON. When I run logstash, I get an error called "Missing Converter handling". I do understand that is java/logstash doesn't recognize the JSON type column.
I can typecast the column to "col_name::TEXT" which works fine. However, I need that column as JSON in an elastic search index. Is there any workaround?
Note: Keys in the JSON object is not fixed, it varies.
Logstash postgres query example:
input {
jdbc {
# Postgres jdbc connection string to our database, bot
jdbc_connection_string => "***"
# The user we wish to execute our statement as
jdbc_user => "***"
jdbc_password => "***"
# The path to our downloaded jdbc driver
jdbc_driver_library => "<ja_file_path>"
# The name of the driver class for Postgresql
jdbc_driver_class => "org.postgresql.Driver"
# our query
statement => "SELECT col_1, col_2, col_3, json_col_4 from my_db;"
}
}
filter{
}
output {
stdout { codec => json_lines }
}
Need JSON object from PostgreSQL to elastic search.

Avoid conversion of compound types to text

My compound types when returned from PLPGSQL function are converted to text:
dev=# select * from app.user_query_test(3);
user_record | udata_record
-----------------+-------------------
(3,875227490,t) | (3,3,"Bob Smith")
(1 row)
dev=#
I don't want this, I want to receive them on the client side as nested object of data, like this:
{
"user_record": {
"user_id": 3,
"identity_id": 875227490,
"utype": t
},
"udata_record": {
"udata_id": 3,
"user_id": 3,
"full_name": "Bob Smith"
}
}
But, I also don't want JSON, because decoding/encoding to JSON format will require processing time and will affect the performance of my App. So how do I achieve this? I mean how do I put the data on the Client in the exact structure as it is returned by PLPGSQL function without any decoding/encoding process?
My source files are:
DROP TYPE IF EXISTS app.user_reply_t CASCADE;
CREATE TYPE app.user_reply_t AS (
user_id integer,
identity_id integer,
utype boolean
);
DROP TYPE IF EXISTS app.udata_reply_t CASCADE;
CREATE TYPE app.udata_reply_t AS (
udata_id integer,
user_id integer,
full_name varchar(64)
);
DROP TYPE IF EXISTS app.user_info_t CASCADE;
CREATE TYPE app.user_info_t AS (
user_record app.user_reply_t,
udata_record app.udata_reply_t
);
CREATE OR REPLACE FUNCTION app.user_query_test(p_user_id integer)
RETURNS app.user_info_t AS
$$
DECLARE
rec app.user_info_t;
BEGIN
SELECT user_id,identity_id,utype FROM "comp-158572724".users WHERE user_id=p_user_id INTO rec.user_record;
SELECT udata_id,user_id,full_name FROM "comp-158572724".udata WHERE user_id=p_user_id INTO rec.udata_record;
RETURN rec;
END;
$$ LANGUAGE plpgsql;
Tested with Node.js:
src $ node usertest.js
result={ command: 'SELECT',
rowCount: 1,
rows:
[ { user_record: '(3,875227490,t)',
udata_record: '(3,3,"Bob Smith")' } ],
fields:
[ { name: 'user_record', dataTypeID: 19862 },
{ name: 'udata_record', dataTypeID: 19865 } ] }
^C
src $
Source of Client code:
src $ cat usertest.js
const util = require('util');
pg = require('pg').native
var Pool = pg.Pool
var Client = pg.Client
var pool=new Pool({
user: 'dev_user',
password: 'dev',
host: 'localhost',
database: 'dev'
});
pool.query('select * from app.user_query_test(3)',function(err, result) {
console.log('result=' + util.inspect(result));
}
);
function wait() {
console.log('wating...');
setTimeout(wait,3000);
}
setTimeout(wait,3000);
src $