I'm trying to fill a sqlite3 database with Python3 with data stored in a dict. The problem in my code seems to be in this snippet.
matchlist=['id','handicap','goal line','corner line']
heads='"'+'","'.join([a for a in list(match.keys()) if a in matchlist])+'"'
llaves=':'+',:'.join([a for a in list(match.keys()) if a in matchlist])
cur.execute('''INSERT or IGNORE INTO preodds ({}) VALUES ({});'''.format(heads,llaves),
match)
This gives me an operational error next to line.
Apparently, when you try to insert in columns which name has blank spaces youneed to"escape" them. To do so, I modified as well my llaves string, doing the following:
llaves='":'+'",":'.join([a for a in list(match.keys()) if a in matchlist])+'"'
Doing so fix my issue, but instead of filling the table with the value provided my the dict, it is filled with the literal value in llaves string.
Why is this? and more importantly, if i have a table with columns with blank spaces, how do you fill rows using dict data?
Your original code is likely producing this
INSERT or IGNORE INTO preodds ("id","handicap","goal line","corner line")
VALUES (:id,:handicap,:goal line,:corner line)
Notice the spaces in the parameters names... the names starting with colon (:). That's the problem.
Your attempted solution is just submitting string literals as values, so that is exactly what is inserted.
INSERT or IGNORE INTO preodds ("id","handicap","goal line","corner line")
VALUES (":id",":handicap",":goal line",":corner line")
Quotes can be used to delimit object names, but in other contexts quotes are interpreted as literal string value delimiters. Precise rules for determining how it interprets quoted values are found here.
As far as I can tell, parameters cannot be escaped and so cannot contain spaces or other special characters, at least nothing that is documented. See sqlite docs.
If you are going to build the parameter list dynamically, you should strip out all spaces from the parameter names. Or alternatively, you could just use unnamed parameters using the ? character. Either way the parameters are assigned values in the order they appear, so there would be no difference.
Something like:
INSERT or IGNORE INTO preodds ("id","handicap","goal line","corner line")
VALUES (:id,:handicap,:goalline,:cornerline)
or
INSERT or IGNORE INTO preodds ("id","handicap","goal line","corner line")
VALUES (?, ?, ?, ?)
Related
In the image, 'muddle' is the string containing junk words and the strings I want to extract. There is a fixed list of junk words - the good strings could be literally anything.
You can see this formula has correctly extracted "moo" and "coo", which are not in the list of junk words. The formula is below.
=LET(junkStart,FILTER(SEARCH(Table1[junkwords],Table2[muddle]),ISNUMBER(SEARCH(Table1[junkwords],Table2[muddle]))),
junkEnd,FILTER(SEARCH(Table1[junkwords],Table2[muddle])+LEN(Table1[junkwords])-1,ISNUMBER(SEARCH(Table1[junkwords],Table2[muddle])+LEN(Table1[junkwords])-1)),
goodstart,FILTER(junkEnd+1,(junkEnd+1<=LEN(Table2[muddle]))*(ISERROR(XMATCH(junkEnd+1,junkStart)))),
goodend,FILTER(junkStart-1,(junkStart-1>=LEN(1))*(ISERROR(XMATCH(junkStart-1,junkEnd))))+1,
goodchars,goodend-goodstart,
TEXTJOIN("; ",TRUE,MID(Table2[muddle],goodstart,goodchars)))
This works well, but it falls down if a junk word occurs more than once. See below.
The only difference is that 'woo' occurs twice in the second example.
I need a single cell solution. VBA is not an option for me. Using the name manager would be untidy, as would nested formulas.
I've got this far with formulas, which as far as I can tell is the furthest anyone has got with the 'removing multiple words from a cell' problem. I can see the issue - once SEARCH locates the start of a string in a cell, it doesn't go looking for a second occurrence of that string. But I don't know how to find the start of every instance of every string. Can anyone help?
REDUCE is perfect for this:
=REDUCE(Table2[muddle],Table1[junkwords],LAMBDA(m,j,SUBSTITUTE(m,j,"")))
REDUCE starts at the Table2[muddle] value as m then it substitutes the first value of Table1[junkwords] j with "" the outcome becomes the new m which will get a substitute of the second value of j. The result will be the new m, etc.
If you would want to have it comma separated it becomes more complicated, but you can realize by:
=LET(t,SUBSTITUTE(","&REDUCE(Table2[muddle],Table1[junkwords],LAMBDA(x,y,SUBSTITUTE(x,y,",")))&",",",,",","),
MID(t,2,LEN(t)-3))
This does almost the same as the previous solution, but instead of substituting for blanks it substitutes for , and substitutes all duplicate ,, for singles, so if more substitutes followed eachother it results in one comma. Also, if the first and/or last part got substituted by a single ,, then the result would have a leading and/or trailing ,. This is solved by first adding , in the front and back before substituting the double comma's for singles. the result t is then wrapped in MID, where the first and last character (both being a ,) are removed.
Alternate solution:
=LET(t,REDUCE(Table2[muddle],Table1[junkwords],LAMBDA(x,y,SUBSTITUTE(x,y," "))),
SUBSTITUTE(TRIM(t)," ",","))
Or in one go if you don't want to use LET:
=SUBSTITUTE(TRIM(REDUCE(Table2[muddle],Table1[junkwords],LAMBDA(x,y,SUBSTITUTE(x,y," "))))," ",",")
This replaces the junk words with a space. Regardless how many junk words in between words or how many trailing or leading spaces TRIM will fix it to the words separated by one space only. Substituting the spaces for comma gets to your result.
There's no single-formula solution if the junkwords list is not fixed.
Instead, you may choose to use the Substitute() function on each cell of the "Extracted Strings" column to substitute all occurances of each junk word in muddle, i.e. substitute "boo" muddle, then substitute "voo" in the resulted string, replace "noo" in the resulted string...so on. You will get the last cell.
One point to note though, you need to ensure no substring / partial strings problem in the junkwords or you need to define the rules of processing in order for the solution to be "complete". Consider the followings:
junk words = abc, def, cde
muddle = 1234abcdef5678
if you process the string in the above order, you got "12345678"
if you process the junk words in reverse order, you got "123abf5678"
I have a string like "Column";"Column";"Column".
However, several times I see:
"Column";"Column;";"Column"
(Notice the extra semicolon in the second field).
Is it possible to find all instances where a semicolon (;) is not surrounded by double quotes (") and replace these with nothing?
something like replace(#string,'[a-z][0-9];','') ?
"Column";"Column;";"Column" turns into "Column";"Column";"Column"
"Value";"Value;";"Value" turns into "Value";"Value";"Value"
"Something";";Something else;";"Another ;thing" turns into "Something";"Something else";"Another thing"
Without knowing your table's definition, this is a vague answer.
In SQL Server 2017 (if I recall correctly), support for CSV formats were added to BULK INSERT, meaning that you could specify both your column and row separators and quote identifiers. For the above, this would mean your FIELDTERMINATOR would need the value ';' and the FIELDQUOTE would need the value '"'. This will, however, leave the remaining ; characters that are surrounded in double quotes.
As such, what I would propose is to create a staging table, where all the columns are a (n)varchar, BULK INSERT your data into that and then INSERT the data into your production table, with REPLACE operators to remove the remaining ; characters and strongly typing them.
In pseudo-SQL this would look like something like this:
BULK INSERT Staging.YourTable
FROM 'C:\YourFilePath\YourFile.txt'
WITH (FORMAT='CSV',
FIELDQUOTE='"',
FIELDTERMINATOR=';');
INSERT INTO Production.YourTable (Column1, Column2, Column3, Column4)
SELECT REPLACE(Column1,';',''),
TRY_CONVERT(int,REPLACE(Column2,';','')),
TRY_CONVERT(date,REPLACE(Column3,';',''),103),
REPLACE(Column4,';','')
FROM Staging.YourTable;
Not sure if this is oversimplification, but if you really have that string in a #string then I see no reason this shouldn't work:
replace(#string, ';";"', '";"')
I'm using Mariadb and have the table setup with VARCHAR(30). When I insert a string containing numbers like "192" and then select it I'm able to print out 192. When I insert a string like "a48" it just seems to be ignored. I've tried inserting a complete letter string "a" and I still get nothing. In the Mariadb documentation for VARCHAR(M) I found this:
"If a unique index consists of a column where trailing pad characters are stripped or ignored, inserts into that column where values differ only by the number of trailing pad characters will result in a duplicate-key error"
I'm not sure if that could have anything to do with it? I am using letters just to make it easier to parse the data on my client side program. If I don't find a solution I will probably just pad it on the server after selecting.
Does anybody have any suggestions on what's going on here, or things I could try to find the problem?
Assuming that melon is the column to receive the string, then you should put single quotes around the $melon variable in the query, like this:
query("REPLACE INTO state (id, melon, image) VALUES (1, '$melon', $image)");
String values should be surrounded by single quotes; numeric values don't need to be.
Because the target column is a varchar(30) the value should always be surrounded by single quotes. MariaDB works out what you mean when you supply a numeric value, but it doesn't understand an alphanumeric value without single quotes. Both will work if you use single quotes, as shown.
To avoid SQL injection errors, it is better to use prepared statements, as described at https://www.w3schools.com/php/php_mysql_prepared_statements.asp.
Python 3.4
I've got an Excel file with some messy organizing, but one this is for sure:
I need EVERYTHING except the stuff that appears before the very first comma in every single line, the comma included.
Example:
Print command of the file gives me this:
Word1 Funky,Left Side,UDLRDURLUDRUDLUR
Nothing (because not) exists lol extraline,Right
Side,RBRGBRGBRGRBGRBGBR
What I want to get is this:
Left Side,UDLRDURLUDRUDLUR
Right Side,RBRGBRGBRGRBGRBGBR
I'd also like to make that into a dictionary:
dictionary = {"Left Side":"UDLRDURLUDRUDLUR", "Right Side":"RBRGBRGBRGRBGRBGBR",}
So basically I want to get rid of everything until the first comma (comma included), make the second part the key (ends at second comma), and third part the value (line ends with value).
What would be the easiest way to execute this?
Suppose s contains the string to be examined:
s = "word1,Left Side,UDLRDURLUDRUDLUR"
There are a number of ways to get rid of everything up to and including the first comma. You can use
Slicing coupled with find: s[s.find(',')+1:]
This expression will yield the desired result if the string s contain at least one comma, but it will yield the entire string if the string does not contain any commas.
Split coupled with indexing: s.split(',',1)[1]
This expression will yield the desired result if the string s contain at least one comma, but it will raise IndexError if the string does not contain any commas.
Regular expressions, but that's overkill here.
Other techniques, but those are also overkill here.
I have come across the following issue with Fortran: that in reading a character array, for example, or any list in actuality, from a data file with fmt=*, both non-interquote blanks AND commas are natively considered as delimiters for the elements in the array/list. The fact that commas act as delimiters is a big problem for me.
So the question is: do you know of any semantic option or compilation directive in Fortran that permits to consider the commas in input files as characters and not as delimiters,
with the only delimiters being blanks? As an specific example, I would like that when reading a record like:
x,y,z
with:
read (7,*) adummy
would result in adummy (a scalar character variable) getting the value x,y,z not x.
Any help would be most welcome.
The solution is to specify formatting to match your data record, i.e. use character data descriptor when specifying the format:
read(7,fmt='(A)')adummy
will result in adummy having value x,y,z, assuming it is a variable of sufficient length.
However this method will not treat blanks as delimiters either, so if you want to read commas as character strings but have blanks as delimiter, the common way to achieve this is to read the whole record into the character variable and do the splitting into separate variables afterwards.