Dropbox: /delta and shared folders - python

I'm using the /delta feature to find whether anything has changed in the Dropbox account.
When I run it for the first time (till 'has_more' becomes False), it's fine. But when I run it again (with the cursor from the previous call), it shows a list of files. I run it again (without changing any file), and I still get the same list of files (although they hadn't changed). I figured that these files were in a shared folder.
I tested again with a new set of files in that folder and I get the same result -- these files show up in the delta entries although they weren't changed.
What's wrong?
I feel this is a bug. Any way to get around it?
Edit:
Here's the code
def getDeltaEntries(self): #this function is a method of a class
def _getDelta():
delta = self.client.delta(self.cursor)
entries = delta.get('entries')
has_more = delta.get('has_more')
self.cursor = delta['cursor']
while has_more:
delt = self.client.delta(self.cursor)
entries.extend(delta.get('entries'))
has_more = delt.get('has_more')
self.cursor = delta['cursor']
return entries
#workaround: query for delta twice and if the result is the same both times,
#it implies there's no change
ent1 = _getDelta()
ent2 = _getDelta()
if ent1 == ent2:
entries = []
else:
entries = ent1
return entries

It looks like your code is using self.cursor = delta['cursor'] when it should be using self.cursor = delt['cursor'].

Related

Insert data from a SQL query into a tkinter Entry field

I'm trying to put data from a database (SQLite3) into a set of entry fields in Tkinter.
My hope is that the data-snippets that exist in the database query will be put into the entries to show the user what info is in the db and give the choice to update empty fields.
I however have a hard time dealing with the returned None fields from the DB. None cannot be inserted into entries using .insert()
I've tried to sanitize the data first but since the different data are ints and text's I have not find a suitable replacement. I would also prefer the entries to be empty unless there is actual data to place there.
I've also tried to do an if statement before each line in the vendors_to_fields function but that did not work and seemed really messy.
Bonus question:
Is there a better way to insert values from a tuple into the different entries? I've been thinking about making 2 lists and using list comprehension but I could not solve it.
I hope I make sense, this has been a long coding session
Thank you for all input
My code:
def Order_window():
ord_win = Toplevel(root)
ord_win.title('Orders')
ord_win.geometry('800x600')
i = 0
# Functions
def controller():
vendor_list = list(vendors)
if i <= len(vendor_list):
vendor = vendor_list[i]
print(vendor)
data_from_db(vendor)
else:
vendor_name['text'] = 'All orders are done'
def data_from_db(vendor):
vendor_info_tuple = db.execute(
'SELECT * FROM vendors WHERE (vendor_id = ?)', [vendor])
vendor_info_tuple = vendor_info_tuple.fetchone()
connection.commit()
vendor_info = list(vendor_info_tuple)
if vendor_info[0] is None:
vendor_name['text'] == 'Vendor not in DB, better call Sal'
else:
print(vendor_info)
vendor_to_fields(vendor_info)
def vendor_to_fields(vendor_info):
for field in vendor_info:
if field is None:
vendor_info[field] = 0
print(vendor_info)
vendor_name['text'] = vendor_info[1]
vendor_min1.insert(0, vendor_info[5])
vendor_email.insert(0, vendor_info[2])
vendor_cc.insert(0, vendor_info[3])
vendor_message.insert(0, vendor_info[4])
def next_vendor():
pass
def update_db():
pass
# Layout order window
Label(ord_win, text='Vendor').grid(row=0)
Label(ord_win, text='Min order value').grid(row=1)
Label(ord_win, text='Email').grid(row=2)
Label(ord_win, text='CC').grid(row=3)
Label(ord_win, text='Message').grid(row=4)
vendor_name = Label(ord_win).grid(row=0, column=1)
vendor_min1 = Entry(ord_win)
vendor_min1.grid(row=1, column=1)
vendor_email = Entry(ord_win)
vendor_email.grid(row=2, column=1)
vendor_cc = Entry(ord_win)
vendor_cc.grid(row=3, column=1)
vendor_message = Entry(ord_win)
vendor_message.grid(row=4, column=1)
controller()

How can I pass a Python parameter in config.py to .sql file?

I am using Python Snowflake connector to extract data from tables in Snowflake. Here is my file structure:
sql
a.sql
b.sql
c.sql
configurations.py
data_extract.py
main.py
Here the sql folder contains all my sql queries in .sql files. I put these sql files separately because they are handreds of lines long each and looks messy if I put them into python files.
configuration.py contains datetime parameters I want to change every time I run the code. It looks like this:
START_TIME = '2018-10-01 00:00:00'
END_TIME = '2019-04-01 00:00:00'
I want to add these parameters into the .sql files. For example, a.sql includes the following content:
DECLARE
#START_PICKUP_DATE DATE,
#END_PICKUP_DATE DATE,
SET
#START_PICKUP_DATE = '2018-10-01'
SET
#END_PICKUP_DATE = '2019-04-01'
select supplier_confirmation_id, pickup_datetime, dropoff_datetime, pickup_station_distance
from SANDBOX.ZQIAN.V_PDL
where pickup_datetime >= START_PICKUP_DATE and pickup_datetime < END_PICKUP_DATE
and supplier_confirmation_id is not null;
I use a.sql in my python code in the following way:
def executeSQLScriptsFromFile(filepath):
# snowflake credentials, replace SECRET with your own
ctx = snowflake.connector.connect(
user='S_ANALYTICS_USER',
account=SECRET_A,
region='us-east-1',
warehouse=SECRET_B,
database=SECRET_C,
role=SECRET_D,
password=SECRET_E)
fd = open(filepath, 'r')
query = fd.read()
fd.close()
cs = ctx.cursor()
try:
cur = cs.execute(query)
df = pd.DataFrame.from_records(iter(cur), columns=[x[0] for x in cur.description])
finally:
cs.close()
ctx.close()
return df
def extract_data():
a_sqlpath = os.path.join(os.getcwd(), 'sql\a.sql')
a_df = executeSQLScriptsFromFile(a_sqlpath)
return a_df
The problem is I want START_PICKUP_DATE and END_PICKUP_DATE in a.sql file to be synced and equal to START_TIME and END_TIME in configurations.py file so that I only need to change START_TIME and END_TIME in configurations.py and extract data in different timeframe using a.sql in Snowflake.
I've been looking for solutions online for quite a long time, but still not able to find a good solution that is specific to my problem. Many thanks to anyone who can provide a hint!
You should be able to parameterize the sql statements so that instead of declaring in the SQL file you can just make it a parameter passed during execution.
select supplier_confirmation_id, pickup_datetime, dropoff_datetime, pickup_station_distance
from SANDBOX.ZQIAN.V_PDL
where pickup_datetime >= %(START_PICKUP_DATE)s and pickup_datetime < %(END_PICKUP_DATE)s and supplier_confirmation_id is not null;
Then when calling the function, just send the parameters START_PICKUP_DATE and END_PICKUP_DATE as parameters to the execute statement. One way to do this is to do a mapping from the parameter name to the value of the parameter. (In this example I'm assuming you have a function that will get the parameter value).
cur = cs.execute(query, {'START_PICKUP_DATE':get_value_from_config('start_pickup'), 'END_PICKUP_DATE':get_value_from_config('end_pickup')})
Or you can pass them by location
cur = cs.execute(query, [get_value_from_config('start_pickup'), get_value_from_config('end_pickup')])
Which in essense becomes
cur = cs.execute(query, ['2018-10-01 00:00:00','2019-04-01 00:00:00'])
To accomplish this, I would take your .sql files and extract the queries into triple-quoted python strings with format specifiers for your variables. Then import the queries into your main script just like you import your configuration:
sql_queries.py:
sql_a = """
DECLARE
#START_PICKUP_DATE DATE,
#END_PICKUP_DATE DATE,
SET
#START_PICKUP_DATE = {START_TIME}
SET
#END_PICKUP_DATE = {END_TIME}
select supplier_confirmation_id, pickup_datetime, dropoff_datetime, pickup_station_distance
from SANDBOX.ZQIAN.V_PDL
where pickup_datetime >= START_PICKUP_DATE and pickup_datetime < END_PICKUP_DATE
and supplier_confirmation_id is not null;
"""
main:
from sql_queries import sql_a
print(sql_a.format(configuration.START_TIME, configuration.END_TIME))

Short description isn't working for delete selected (delete_selected.short_description isn't changing the name)

I am currently trying to change the name of the "Delete Selected" admin action. I have already effectively override the default (so I can store some data before completely deleting it), but now I want to change the option from the vague "Deleted selected" to something more specific like "Deleted all selected registrations." Or, at least, for it to say, "Deleted selected registrations" like it did before I overwrote the function.
I have so far tried this:
delete_selected.short_description = 'Delete all selected registrations'
But the option is still "Deleted selected." Is there a way to fix this?
Here's my code:
def delete_selected(modeladmin, request, queryset):
"""
This overrides the defult deleted_selected because we want to gather the data from the registration and create a
DeletedRegistration object before we delete it.
"""
for registration in queryset:
reg = registration.get_registrant()
if registration.payment_delegation:
delegate_name = registration.payment_delegation.name
delegate_email = registration.payment_delegation.email
else:
delegate_name = None
delegate_email = None
registration_to_delete = DeletedRegistration.objects.create(
registrant_name = reg.full_name(),
registrant_email = reg.email,
registrant_phone_num = reg.phone,
delegate_name = delegate_name,
delegate_email = delegate_email,
# Filtering out people (with True) who couldn't participate in events because we are only interested in the people
# we had to reserve space and prepare materials for.
num_of_participants = registration.get_num_party_members(True),
special_event = registration.sibs_event,
)
registration.delete()
delete_selected.short_description = 'Delete all selected registrations'
edit: just tried delete_selected.list_display that didn't work either
You can't have it in the function, so I just had to tab it back one space and it worked.
example:
def delete_selected(modeladmin, request, queryset)
code
delete_selected.short_description = "preferred name"
thanks.

not able to undertand cursors in appengine

I'm trying to fetch results in a python2.7 appengine app using cursors, but each time I use with_cursor() it fetches the same result set.
query = Model.all().filter("profile =", p_key).order('-created')
if r.get('cursor'):
query = query.with_cursor(start_cursor = r.get('cursor'))
cursor = query.cursor()
objs = query.fetch(limit=10)
count = len(objs)
for obj in objs:
...
Each time through I'm getting same 10 results. I'm thinkng it has to do with using end_cursor, but how do I get that value if query.cursor() is returning the start_cursor. I've looked through the docs but this is poorly documented.
Your formatting is a bit screwy by the way. Looking at your code (which is incomplete and therefore potentially leaving something out.) I have to assume you have forgotten to store the cursor after fetching results (or return to the user - I am assuming r is a request ?).
So after you have fetched some data you need to call cursor() on the query. e.g This function counts all entities using a cursor.
def count_entities(kind):
c = None
count = 0
q = kind.all(keys_only=True)
while True:
if c:
q.with_cursor(c)
i = q.fetch(1000)
count = count + len(i)
if not i:
break
c = q.cursor()
return count
See how after fetch() has been called the c=q.cursor() call and it's is used as the cursor next time through the loop.
Here's what finally worked:
query = Model.all().filter("profile =", p_key).order('-created')
if request.get('cursor'):
query = query.with_cursor(request.get('cursor'))
objs = query.fetch(limit=10)
cursor = query.cursor()
for obj in objs:
...

How to save and load QListWidjet contents to/from QSetting with PyQt4?

I've got a QListWidget in my PyQt4 app. It contains folders paths.
I want to save its contents to QSettings and load them later.
I used this code to do this:
def foldersSave(self):
folders = {} '''create dict to store data'''
foldersnum = self.configDialog.FolderLIST.count() '''get number of items'''
if foldersnum:
for i in range(foldersnum):
folders[i] = self.configDialog.FolderLIST.item(i).text() '''save items text to dict'''
return str(folders) '''return string of folders to store in QSettings'''
return None
But if I make so folders paths are stored in config file like:
musicfolders={0: PyQt4.QtCore.QString(u'/home/sam/Ubuntu One')}
So I have no idea how to load them then. I've tryed something like this in different variants:
def foldersLoad(self):
folders = eval(self.tunSettings.value('musicfolders').toString())
It returns error:
TypeError: eval() arg 1 must be a string or code object
It looks like I just need to save data some other way then I do now.
Gooled a lot, but have no clue. I'm sure the answer is trivial, but I'm stuck.
The solution is very simply. I were to use QStringList.
def foldersSave(self):
folders = QtCore.QStringList()
foldersnum = self.configDialog.FolderLIST.count()
if foldersnum:
for i in range(foldersnum):
print (i, " position is saved: ", self.configDialog.FolderLIST.item(i).text())
folders.append(self.configDialog.FolderLIST.item(i).text())
return folders
return None
and load
def foldersLoad(self):
folders = QtCore.QStringList()
folders = self.tunSettings.value('musicfolders', None).toStringList()
if folders.count():
foldersnum = folders.count()
for i in range(foldersnum):
self.configDialog.FolderLIST.addItem(folders.takeFirst())

Categories