I want to generate a string for updating values in SQL, from a python dict.
So far, I have the following:
def sqlquote(value):
"""Naive SQL quoting
All values except NULL are returned as SQL strings in single quotes,
with any embedded quotes doubled.
"""
if value is None:
return 'NULL'
return '"{}"'.format(str(value).replace("'", "''"))
part1="UPDATE products_list SET"
#This parts prints with the desired format, but I don't know how to create a string with this:
part2:
for key, value in article_dict.items():
print(key, '=', sqlquote(value))
part3="WHERE product_id=article_dict['product_id']
How can I "concat" the part2 of the string to make a unique string that can be used later to update a sqlite database?
The SQL you're producing isn't valid, since you're missing spaces between the different parts. Also, there's no need for the sqlquote function, it's better to use bound parameters:
values = []
sql = "UPDATE products_list SET "
# For each item in the dictionary, add to the SQL string
temp = []
for key, value in article_dict.items():
if key != 'product_id':
temp.append(f"{key}=?")
# And store the value in a seperate list
values.append(value)
# Concat the different set instructions
sql += ",".join(temp) + " "
# And add a WHERE clause to the end
sql += "WHERE product_id=?;"
values.append(article_dict['product_id'])
# TODO:
# db.execute(sql, values)
Related
I have what I think is a basic question in Python:
I have a list that can be variable in length and I need to insert it into a string for later use.
Formatting is simple, I just need a comma between each name up to nameN and parenthesis surrounding the names.
List = ['name1', 'name2' .... 'nameN']
string = "Their Names are <(name1 ... nameN)> and they like candy.
Example:
List = ['tom', 'jerry', 'katie']
print(string)
Their Names are (tom, jerry, katie) and they like candy.
Any ideas on this? Thanks for the help!
# Create a comma-separated string with names
the_names = ', '.join(List) # 'tom, jerry, katie'
# Interpolate it into the "main" string
string = f"Their Names are ({the_names}) and they like candy."
There are numerous ways to achieve that.
You could use print + format + join similar to the example from #ForceBru.
Using format would make it compatible with both Python2 and Python3.
names_list = ['tom', 'jerry', 'katie']
"""
Convert the list into a string with .join (in this case we are separating with commas)
"""
names_string = ', '.join(names_list)
# names_string == "tom, katie, jerry"
# Now add one string inside the other:
string = "Their Names are ({}) and they like candy.".format(names_string)
print(string)
>> Their Names are (tom, jerry, katie) and they like candy.
I'm trying to replace a specific substring in the keys of a dictionary with this code:
# **kwargs is taken from a function, I'm just showing the content of it
name = 'foobar'
kwargs = {'__async': 'none', 'in_width': 'foo'}
part_of_key_to_replace = {'__': '', '_': '-'}
all_attr = f"<{name} ", *(f" {key.replace((key, value) for key, value in part_of_key_to_replace.items())}='{value}'" for key, value in kwargs.items()), ">"
def join_attr(tup): # Joins the tuple to form a string
string = ''
for item in tup:
string = string + item
string = string.replace(' ', ' ')
return string
print(join_attr(all_attr))
I expected the output to be:
<foobar asnync='none' in-width='foo' >
It instead gives a SyntaxError:
File "<fstring>", line 47
SyntaxError: Generator expression must be parenthesized
I've looked up at other solutions, but they're specific to an old version of Django, which I'm not working with here.
How do I rectify this? Is there a more efficient way to do this?
I'm guessing there's an issue with the *(f"...") part.
Thanks.
I am getting information from a file which has content such as the one below:
1:Record:Place1:Ext12
2:Record:Place2:Ext2
3:Record:Place1:Ext19
4:Record:Place1:Ext12
I am trying to store words such as Place1 and Place2 in dictionary as keys and then count their occurrences and store the integer count as values to those keys respectively.
file = open('./Records.txt', mode='r')
d_file = file.read()
location = dict()
count = 0
for item in d_file.splitlines():
items = item.split(':')
key = items[2]
if key == items[2]:
count += 1
location[key] = count
print(location)
There is a Counter feature in the collections module. (Click to read official documentation)
It does exactly what you want. It takes an iterable or mapping and returns a dict of keys and number of occurrences as value.
from collections import Counter
#open file, etc
keys = [item.split(':')[2] for item in d_file.splitlines()]
print(Counter(keys))
In the above snippet, a list of all key occurrence is made according to your format, then a dictionary of number of occurrences is printed.
The file is assumed to have correctly formatted lines, so item.split(':')[2] exists. I recommend looking at this answer for safer str partitioning How do I reliably split a string in Python, when it may not contain the pattern, or all n elements?
I'm running the linux terminal command 'strings' on a file and storing the result, which is a series of readable strings, in a variable. The results are also written to a text file. I then need to upload the results to a database. The problem is that the result often contains ' and " characters in an unpredictable order. These cause an SQL error. I've tried to string.replace with an empty string and a \ escape. I've also tried """ or ''' round the string but neither work as I don't know which type of quotation mark will be first. Any suggestions would be appreciated.
fileName = filePath.rsplit('/', 1)[1]
stream = os.popen('strings ' + filePath)
output = stream.readlines()
file = open(filePath + "/" + fileName + "_StringsResults.txt", "w+")
for o in output:
file.write(str(o))
results += str(o)
file.close()
dsn = 'postgresql://############localhost:########/test?sslmode=disable'
conn = psycopg2.connect(dsn)
with conn.cursor() as cur:
cur.execute(
"UPSERT INTO test (testID) VALUES ('%s')" % (results))
conn.commit()
yes that worked, thanks a million. For anyone else who's interested the solution was roughly:
query = """UPSERT INTO test (testID) VALUES (%s)"""
#Connection code etc.
with conn.cursor() as cur:
cur.execute(query, [results])
conn.commit()
The [] round the parameter was necessary to avoid a type error.
I have a big chunk of json code. I assign the needed me values to more than +10 variables. Now I want to print all variable_name = value using print how I can accomplish this task
Expected output is followed
variable_name_1 = car
variable_name_2 = house
variable_name_3 = dog
Updated my code example
leagues = open("../forecast/endpoints/leagues.txt", "r")
leagues_json = json.load(leagues)
data_json = leagues_json["api"["leagues"]
for item in data_json:
league_id = item["league_id"]
league_name = item["name"]
coverage_standings = item["coverage"]["standings"]
coverage_fixtures_events =
item["coverage"]["fixtures"]["events"]
coverage_fixtures_lineups =
item["coverage"]["fixtures"]["lineups"]
coverage_fixtures_statistics =
item["coverage"]["fixtures"]["statistics"]
coverage_fixtures_players_statistics = item["coverage"]["fixtures"]["players_statistics"]
coverage_players = item["coverage"]["players"]
coverage_topScorers = item["coverage"]["topScorers"]
coverage_predictions = item["coverage"]["predictions"]
coverage_odds = item["coverage"]["odds"]
print("leagueName:" league_name,
"coverageStandings:" coverage_standings,
"coverage_fixtures_events:"
coverage_fixtures_events,
"coverage_fixtures_lineups:"
coverage_fixtures_lineups,
"coverage_fixtures_statistics:"
coverage_fixtures_statistics,
"covage_fixtes_player_statistics:"
covage_fixres_players_statistics,
"coverage_players:"
coverage_players,
"coverage_topScorers:"
coverage_topScorers,
"coverage_predictions:"
coverage_predictions,
"coverage_odds:"coverage_odds)
Since you have the JSON data loaded as Python objects, you should be able to use regular loops to deal with at least some of this.
It looks like you're adding underscores to indicate nesting levels in the JSON object, so that's what I'll do here:
leagues = open("../forecast/endpoints/leagues.txt", "r")
leagues_json = json.load(leagues)
data_json = leagues_json["api"]["leagues"]
def print_nested_dict(data, *, sep='.', context=''):
"""Print a dict, prefixing all values with their keys,
and joining nested keys with 'separator'.
"""
for key, value in data.items():
if context:
key = context + sep + key
if isinstance(value, dict):
print_nested_dict(value, sep=sep, context=key)
else:
print(key, ': ', value, sep='')
print_nested_dict(data_json, sep='_')
If there is other data in data_json that you do not want to print, the easiest solution might be to add a variable listing the names you want, then add a condition to the loop so it only prints those names.
def print_nested_dict(data, *, separator='.', context=None, only_print_keys=None):
...
for key, value in data.items():
if only_print_keys is not None and key not in only_print_keys:
continue # skip ignored elements
...
That should work fine unless there is a very large amount of data you're not printing.
If you really need to store the values in variables for some other reason, you could assign to global variables if you don't mind polluting the global namespace.
def print_nested_dict(...):
...
else:
name = separator.join(contet)
print(name, ': ', value, sep='')
globals()[name] = value
...