How to read the values from one flat file and use them in loop in PostgreSQL file? - psql

The requirement is to read the values from one flat file and use them in for loop to modify the pgSQL queries.
I'm new to PostgreSQL. Please suggest any.
CREATE FUNCTION file_vals()
RETURNS varchar[] AS
$BODY$
return (readLines('my_file.txt'))
$BODY$
language plpgsql;
DO $ANONYMOUS_BLOCK$ declare
/* data */
begin
for c, l in user_c, file_vals()
loop
perform x.y(user => c.user, password => l);
RAISE NOTICE '%', c.user;
end loop;
end $ANONYMOUS_BLOCK$;
I'm trying to read the values from my_file.txt and also use the values in for loop to insert the values in database(x.y is the psql function) .
my_file.txt contains passwords:
a
b
c
d
user_c is cursor, which is having user values.
Need to use both the values i.e, user_c and file_vals in one single for loop statement.
Error:
psql:test.psql:6: ERROR: syntax error at or near "return"
LINE 4: return (readLines('my_file.txt'))
^
SET
psql:test.psql:20: ERROR: "c" is not a known variable
LINE 7: for c, l in user_c, file_vals()

Related

Snowflake Store Procedure - Loop through csv files in AWS S3 and COPY INTO tables with same name

I was wondering if someone could help me with the error message I am getting from Snowflake. I am trying to create a stored procedure that will loop through 125 files in S3 and copy into the corresponding tables in Snowflake. The names of the tables are the same names as the csv files. In the example I only have 2 file names set up (if someone knows a better way than having to liste all 125, that will be extremely. helpful) .
The error message I am getting is the following:
syntax error line 5 at position 11 unexpected '1'.
syntax error line 6 at position 22 unexpected '='. (line 4)
CREATE OR REPLACE PROCEDURE load_data_S3(file_name VARCHAR,table_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
BEGIN
FOR i IN 1 to 2 LOOP
CASE i
WHEN 1 THEN
SET file_name = 'file1.csv';
SET table_name = 'FILE1';
WHEN 2 THEN
SET file_name = 'file2.csv';
SET table_name = 'FILE2';
--WILL LIST THE REMAINING 123 WHEN STATEMENTS
ELSE
-- Do nothing
END CASE;
COPY INTO table_name
FROM #externalstg/file_name
FILE_FORMAT = (type='csv');
END LOOP;
RETURN 'Data loaded successfully';
END;
$$;
There are various ways to list the files in a stage (see the post here). You can loop through the resultset and run COPY INTO on each record

How to create a tables with variable length with string-like keys in lua

I have a file database. Inside that file I have something like:
DB_A = ...
DB_B = ...
.
.
.
DB_N = ...
I would like to parse the data and group them in lua code like this:
data={}
-- the result after parsing a file
data={
["DB_A"] = {...},
["DB_B"] = {...},
.
.
.
["DB_N"] = {...}
}
In other words, is it possible to create a table inside a table dynamically and assign the key to each table without previously knowing what will be the names of the key (that is something I can figure out after parsing the data from a database).
(Just as a note, I am using Lua 5.3.5; also, I apologize that my code resembles C more than Lua!)
Iterating through your input file line-by-line--which can be done with the Lua FILE*'s lines method--you can use string.match to grab the information you are looking for from each line.
#!/usr/bin/lua
local PATTERN = "(%S+)%s?=%s?(%S+)"
local function eprintf(fmt, ...)
io.stderr:write(string.format(fmt, ...))
return
end
local function printf(fmt, ...)
io.stdout:write(string.format(fmt, ...))
return
end
local function make_table_from_file(filename)
local input = assert(io.open(filename, "r"))
local data = {}
for line in input:lines() do
local key, value = string.match(line, PATTERN)
data[key] = value
end
return data
end
local function main(argc, argv)
if (argc < 1) then
eprintf("Filename expected from command line\n")
os.exit(1)
end
local data = make_table_from_file(argv[1])
for k, v in pairs(data) do
printf("data[%s] = %s\n", k, data[k])
end
return 0
end
main(#arg, arg)
The variable declared at the top of the file, PATTERN, is your capture pattern to be used by string.match. If you are unfamiliar with how Lua's pattern matching works, this pattern looks for a series of non-space characters with zero or one spaces to its right, an equal sign, another space, and then another series of non-space characters. The two series of non-space characters are the two matches--key and value--returned by string.match in the function make_table_from_file.
The functions eprintf and printf are my Lua versions of C-style formatted output functions. The former writes to standard error, io.stderr in Lua; and the latter writes to standard output, io.stdout in Lua.
In your question, you give a sample of what your expected output is. Within your table data, you want it to contain keys that correspond to tables as values. Based on the sample input text you provided, I assume the data contained within these tables are whatever comes to the right of the equal signs in the input file--which you represent with .... As I do not know what exactly those ...s represent, I cannot give you a solid example for how to separate that right-hand data into a table. Depending on what you are looking to do, you could take the second variable returned by string.match, which I called value, and further separate it using Lua's string pattern matching. It could look something like this:
...
local function make_table_from_value(val)
// Split `val` into distinct elements to form a table with `some_pattern`
return {string.match(val, some_pattern)}
end
local function make_table_from_file(filename)
local input = assert(io.open(filename, "r"))
local data = {}
for line in input:lines() do
local key, value = string.match(line, PATTERN)
data[key] = make_table_from_value(value)
end
return data
end
...
In make_table_from_value, string.match will return some number of elements, based on whatever string pattern you provide as its second argument, which you can then use to create a table by enclosing the function call in curly braces. It will be a table that uses numerical indices as keys--rather than strings or some other data type--starting from 1.

Lua)) how to loop table of table and get a specific property?

I am really newbie in lua. I have this lua code
local gun_info = {
g_sword={rate=0.5;spd=0;dmg=1;ammo=1;};
g_pistol={rate=0.5;spd=5;dmg=1;ammo=40;};
g_knife={rate=0.8;spd=5;dmg=1;ammo=1;};
g_shuriken={rate=0.3;spd=5;dmg=1;ammo=40;};
g_bomb={rate=0.8;spd=5;dmg=1;ammo=20;};
};
I just want get values of every ammo. Other properties are no needed.
for k, v in pairs(gun_info) do
print(k, v[1], v[2], v[3], v[4], v[5])
end
this prints out whole tables but I need just value of ammos
Use comma between table variables rather than semicolon. Using semicolon is not syntactically wrong but optional in Lua. Semicolon is usually used to separate multiple statements written in single line.
You can directly access the variable ammo by indexing the key of the table
for k, v in pairs(gun_info) do
print(k, v.ammo)
end
v.ammo and v[ammo] are not same in Lua.
Note: The order in which the elements appear in traversal will not be the same as you defined and can produce different order each time. This is due to the way tables are implemented in Lua.

Why lua's syntax sugar not work here(call function with colon)?

I knew some about calling function syntax sugar in lua.
A = {}
function A.func(a) print(tostring(a))end
I have a table A above. And I can call A.func like this A.func(A)
, also I can call like this A:func()
But when I save A and A.func in a table B, and then try to call back. Error happened, which is "attempt to call a nil value (method 'v')"
B = {}
B[A] = A.func
--call A.func
k,v = next(B)
k:v()--error happened here
v(k)--no error occurred
So, I just wonder what happened here when I use syntax sugar?
Syntax sugar makes these commands equivalent
> A["func"](A)
table: 009F7E58
> A.func(A)
table: 009F7E58
> A:func()
table: 009F7E58
So if try to execute command k:v() it's the same as k["v"](k). But your table k has no record "v", it has record "func". So you can run
> k["func"](k)
table: 009F7E58
or
> v(k)
table: 009F7E58
or
> k:func()
table: 009F7E58
As you can see, variable "v" contains the function itself, not the name of function in the table k. But if want to use syntax sugar, you need to know a name of the record with function in the table.
P.S. Yes, in your example "k" and "A" are names of the same table (009F7E58).
When you use k:v() v doesn't reffer to local variable v above. k:v() syntax telling lua to find function called v in object k and execute it, passing k as first parameter.
Another example probably show this behavior better:
k = {}
function k.v(a) print(tostring(a))end
local function v(a) print("local func called", a) end
k:v() -- this method always call k.v function
-- no matter that variable with same name exists

Lua: When and how to write tables to _G

I am learning Lua from a book, and I am NOT a programmer. I am trying to save a table of data to a file using the following functions (that were copied directly from the book), but the function is getting an error when trying to get a string from _G[resTable]. Why?
function readFromFile(filename,resTable)
local hfile = io.open(filename)
if hfile == nil then return end
local results = {} -why is this table here?
local a = 1
for line in hfile:lines() do-- debug shows this loop doesn't run (no lines in hfile?)
_G[resTable[a]] = line
a = a + 1
end
end
function writeToFile(filename, resTable)
local hfile = io.open(filename, "w")
if hfile == nil then return end
local i
for i=1, #resTable do
hfile:write(_G[resTable[i]])--bad argument #1 to 'write' (string expected, got nil)
end
end
'writeToFile" gets an error when trying to :write to _G[resTable[i]]. In the two previous functions listed here, I don't understand why they are referencing _G[resTable[i]] since I don't see any code that is writing to _G.
So here is the order of execution:
local aryTable = {
"Score",
"Lives",
"Health",
}
readFromFile("datafile", aryTable)
writeToFile("datafile", aryTable)
and I get an error:
bad argument #1 to 'write' (string expected, got nil)
stack traceback:
[C]: in function 'write'
test.lua:45: in function 'writeToFile'
test.lua:82: in main chunk
Apparently the author has implemented a way of saving a list of global variables to file and restore them.
The function writeToFile expects a filename and a list of global variables names (resTable). Then it opens a the filename for writing and iterates over the provided names:
for i=1, #resTable do
hfile:write(_G[resTable[i]])
end
in this loop resTable[i] is the i-th name and _G[resTable[i]] is the corresponding value, taken from the table _G, which stores all the globals. If a global with that name is not defined, _G[resTable[i]] will return nil, which is the cause of the failure you experienced. Thus you must provide a resTable that is filled with names of existing globals to avoid this error.
Apart from this, the serialization strategy of the author is really naive, since it handles only variables with string values. In fact by saving the variables to file like that the type information is lost, thus a variable having the value "100" (a string) and another with value 100 (a number) will be stored the same on disk.
The problem is evident analyzing the readFromFile function. After opening the file for reading, it scans it line by line, creating a new variable for each name mentioned in its resTable list:
local a = 1
for line in hfile:lines() do
_G[resTable[a]] = line
a = a + 1
end
the problem is manyfold:
the loop variable line will always have a string value, thus the recreated globals will be all strings, even if they were numbers originally;
it assumes that the variables are recreated in the same order, thus you must provide the same names in resTable you used when you saved the file;
it assumes that the values are stored one per line, but this is a false assumption, since the writeToFile function doesn't write a newline character after each value;
Moreover that local results = {} is useless and in both functions the file handle hfile is not closed. This latter is very bad practice: it could waste system resources and if your script fails part of the supposedly written data could never make its way to disk, since it may be still stuck in some buffer. File handles are automatically closed when the script ends, but only if it ends in a sane way.
Unless you did some error in pasting the code or omitted significant parts of it or the book is building some example incrementally, I dare say it is fairly crappy.
If you want a quick and dirty way to save and retrieve some globals you could use this:
function writeToFile( filename, resTable )
local hfile = io.open(filename, "w")
if hfile == nil then return end
for _, name in ipairs( resTable ) do
local value = _G[name]
if value ~= nil then
hfile:write( name, " = ")
local vtype = type( value )
if vtype == 'string' then
hfile:write( string.format( "%q", value ) )
elseif vtype == 'number' or vtype == 'boolean' then
hfile:write( tostring( value ) )
else
-- do nothing - unsupported type
end
hfile:write( "\n" )
end
end
hfile:close()
end
readFromFile = dofile
It saves the globals as a Lua script and reads them back by executing the script using Lua dofile function. Its main limitation is that it can only save strings, booleans an numbers, but usually this is enough while learning.
You can test it with the following statements:
a = 10
b = "20"
c = "hello"
d = true
print( a, b, c, d )
writeToFile( "datafile", { "a", "b", "c", "d" } )
a, b, c, d = nil
print( a, b, c, d )
readFromFile( "datafile" )
print( a, b, c, d )
If you need more advanced serialization techniques you can refer to Lua WIKI page on table serialization.
Those aren't generalized "read/write any table from/to any file" functions. They apparently expect the name of a global table as an argument, not a [reference to a local] table itself. They look like the kind of one-off solution to a very specific problem that tends to show up in books. :-)
Your functions shouldn't be doing anything with _G. I don't have an API reference handy, but the read loop should be doing something like
resTable[a] = line
and the write loop would be doing
hfile:write(resTable[i])
Throw out that local "results" table too. :-)
This code reads and writes data from a file into global variables whose names are specified in aryTable. Since your file is empty, readFromFile does not actually set the variable values. And then writeToFile fails when trying to get the variable values, because they haven't been set.
Try putting data in the file so that the variables do get set, or set the variable values yourself before writing them to the file (e.g. Score = 10, etc.)

Resources