I have a task in which I must update a database on another server. As my options are limited I'm using python to do the update.
However I have this error:
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near ')'. (102) (SQLExecDirectW)")
My code is this:
first I create a select and then use it in the update
> query_dwt = "SELECT [cdcliente]\
> ,[nmcontato]\
> ,[cddepartamento]\
> ,[nmcargo] \
> ,[dsemail]\
> ,[cdlingua]\
> ,[nrcpfcnpj]\
> ,[cdcargo]\
> ,[cdcontatosuperior]\
> ,[idativo]\
> ,[cdcidade]\
> ,[dsendereco]\
> ,[dscomplemento]\
> ,[nmbairro]\
> ,[nrcep]\
> ,[nrcelular]\
> ,[dtnascimento]\
> ,[idbloqueado]\
> ,[cdlocalidade]\
> ,[nrmatricula]\
> ,[nmskin]\
> FROM [dw].[d_Qualitor_ad_contato_RH] WITH (NOLOCK)\
> WHERE cdcliente = 9402\
> AND (cdcontato = 38584 OR cdcontato = 22320 OR cdcontato = 37284);"
Second I use the select created to bring the information from the table to update the desired table
> query_qltr = """UPDATE ad\
> SET\
> ad.nmcontato = PR.nmcontato\
> ,ad.cddepartamento = PR.cddepartamento\
> ,ad.nmcargo = PR.nmcargo\
> ,ad.dsemail = PR.dsemail\
> ,ad.cdlingua = PR.cdlingua\
> ,ad.nrcpfcnpj = PR.nrcpfcnpj\
> ,ad.cdcargo = PR.cdcargo\
> ,ad.cdcontatosuperior = PR.cdcontatosuperior\
> ,ad.idativo = PR.idativo\
> ,ad.cdcidade = PR.cdcidade\
> ,ad.dsendereco = PR.dsendereco\
> ,ad.dscomplemento = PR.dscomplemento\
> ,ad.nmbairro = PR.nmbairro\
> ,ad.nrcep = PR.nrcep\
> ,ad.nrcelular = PR.nrcelular\
> ,ad.dtnascimento = PR.dtnascimento\
> ,ad.idbloqueado = PR.idbloqueado\
> ,ad.cdlocalidade = PR.cdlocalidade\
> ,ad.nrmatricula = PR.nrmatricula\
> ,ad.nmskin = PR.nmskin\
> FROM dbo.ad_contato ad\
> INNER JOIN ({}) PR\
> ON ad.cdcontato = PR.cdcontato\
> AND ad.cdcliente LIKE '9402';""".format(OpenSqlDatabaseConnection.execute_query(query_dwt,'target-db-conn-str'))
>
> OpenSqlDatabaseConnection.execute_query(query_qltr,'rdn-db-clt-sql-06a-inssql01-qualitor-prd-jdbc-conn-string-01')
I'm sure it's something simple but I can't figure it out.
Solution:
1-Extract the data in the first database and insert it into a dataframe.
def select_dw_qualitor_ad_contato():
query_dwt = "SELECT [cdcliente]\
,[cdcontato]\
,[nmcontato]\
,[cddepartamento]\
,[nmcargo] \
,[dsemail]\
,[cdlingua]\
,[nrcpfcnpj]\
,[cdcargo]\
,[cdcontatosuperior]\
,[idativo]\
,[cdcidade]\
,[dsendereco]\
,[dscomplemento]\
,[nmbairro]\
,[nrcep]\
,[nrcelular]\
,[dtnascimento]\
,[idbloqueado]\
,[cdlocalidade]\
,[nrmatricula]\
,[nmskin]\
FROM [dw].[d_Qualitor_ad_contato_RH] WITH (NOLOCK)\
WHERE cdcliente = 9402\
AND (cdcontato = 38584\
OR cdcontato = 22320\
OR cdcontato = 37284\
OR cdcontato = 36139\
OR cdcontato = 41035\
OR cdcontato = 38819);"
return pd.read_sql(query_dwt,OpenSqlDatabaseConnection.connection('target-db-conn-str'),
parse_dates={"date_column": {"errors": "ignore"}})
2- Update second query row by row with dataframe
def update_qualitor_table():
dfdw = QueriesLists.select_dw_qualitor_ad_contato()
end = len(dfdw)
for i,line in enumerate(dfdw):
if i < end:
df = dfdw.iloc[i]
QueriesLists.update_database(df)
else:
break
3- Query SQL using update command using dataframe
def update_database(df):
query_qltr = "UPDATE [dbo].[ad_contato]\
SET [nmcontato] = CAST('{0}' AS VARCHAR(200))\
,[cddepartamento] = CAST('{1}' AS INT)\
,[nmcargo] = CAST('{2}' AS VARCHAR (50))\
,[dsemail] = CAST('{3}' AS VARCHAR(200))\
,[cdlingua] = CAST('{4}' AS INT)\
,[nrcpfcnpj] = CAST('{5}' AS VARCHAR(20))\
,[cdcargo] = CAST('{6}' AS INT)\
,[cdcontatosuperior] = CAST('{7}' AS INT)\
,[idativo] = CAST('{8}' AS VARCHAR(1))\
,[dsendereco] = CAST('{9}' AS VARCHAR(200))\
,[dscomplemento] = CAST('{10}' AS VARCHAR(200))\
,[nmbairro] = CAST('{11}' AS VARCHAR(40))\
,[nrcep] = CAST('{12}' AS VARCHAR(9))\
,[dtnascimento] = CAST('{13}' AS DATETIME) \
,[idbloqueado] = CAST('{14}' AS VARCHAR(1))\
,[cdlocalidade] = CAST('{15}' AS INT)\
,[nrmatricula] = CAST('{16}' AS VARCHAR(20))\
WHERE [cdcontato] = CAST('{17}' AS INT)\
AND [cdcliente] = 9402;\
".format(str(df[2]) #nmcontato
,int(df[3]) #cddepartamento
,str(df[4]) #nmcargo
,str(df[5]) #dsemai
,int(df[6]) #cdlingua
,str(df[7]) #nrcpfcnpj
,int(df[8]) #cdcargo
,int(df[9]) #cdcontasuperior
,str(df[10]) #idativo
,str(df[12]) #dsendereco
,str(df[13]) #dscomplemento
,str(df[14]) #nmbairro
,str(df[15]) #nrcep
,pd.to_datetime(df[17]) #datetime
,str(df[18]) #idbloqueado
,int(df[19]) #cdlocalidade
,str(df[20]) #nrmatricula
,int(df[1])
)
OpenSqlDatabaseConnection.execute_query(query_qltr,'rdn-db-clt-sql-06a-inssql01-qualitor-prd-jdbc-conn-string-01')
Related
I'm converting a Pinescript Indicator to python to use it with pandas:
Here is pinescrip code:
RSI_Period = input(14,title='RSI')
SF = input(5,title='Slow Factor')
QQE=input(4.236)
Wilders_Period = RSI_Period * 2 - 1
Rsi = rsi(close,RSI_Period)
RsiMa = ema(Rsi, SF)
AtrRsi = abs(RsiMa[1] - RsiMa)
MaAtrRsi = ema(AtrRsi, Wilders_Period)
dar = ema(MaAtrRsi,Wilders_Period) * QQE
DeltaFastAtrRsi= dar
RSIndex=RsiMa
newshortband= RSIndex + DeltaFastAtrRsi
newlongband= RSIndex - DeltaFastAtrRsi
longband=RSIndex[1] > longband[1] and RSIndex > longband[1]?
max(longband[1],newlongband):newlongband
shortband=RSIndex[1] < shortband[1] and RSIndex < shortband[1]?
min(shortband[1], newshortband):newshortband
trend=cross(RSIndex, shortband[1])?1:cross(longband[1], RSIndex)?-1:nz(trend[1],1)
FastAtrRsiTL = trend==1? longband: shortband
plot(FastAtrRsiTL,color=red)
plot(RsiMa,color=yellow)
Now this is what I got so far in python:
RSIPeriod = 14
SF = 5
QQE=4.236
WildersPeriod = RSIPeriod * 2 - 1
df['RSI'] = ta.RSI(df['Price'], RSIPeriod)
df['RSI_ma'] = ta.EMA(df['RSI'], SF)
df['ATRrsi'] = abs(df['RSI_ma'].shift(1) - df['RSI_ma'])
df['MaATRrsi'] = ta.EMA(df['ATRrsi'], WildersPeriod)
df['dar'] = ta.EMA(df['MaATRrsi'], WildersPeriod) * QQE
df['newshortband'] = df['RSI_ma'] + df['dar']
df['newlongband'] = df['RSI_ma'] - df['dar']
df['longband'] = 0.0
df['longband'] = np.where( df['RSI_ma'].shift(1) > df['longband'].shift(1) and df['RSI_ma'] > df['longband'].shift(1),
max(df['longband'].shift(1) ,df['newlongband']), df['newlongband'])
df['shortband'] = 0.0
df['shortband'] = np.where( df['RSI_ma'].shift(1) < df['shortband'].shift(1) and df['RSI_ma'] < df['shortband'].shift(1),
max(df['shortband'].shift(1) ,df['newshortband']), df['newshortband'])
df['trend'] = np.where(df['RSI_ma'] > df['dar'].shift(1), 1, -1)
df['FastAtrRsiTL'] = np.where(df['trend'] == 1, df['longband'], df['shortband'])
And this is the error:
----> 4 df['longband'] = np.where( df['RSI_ma'].shift(1) > df['longband'].shift(1) and df['RSI_ma'] > df['longband'].shift(1),
5 max(df['longband'].shift(1) ,df['newlongband']), df['newlongband'])
6 df['shortband'] = 0.0
~\Anaconda3\envs\finance\lib\site-packages\pandas\core\generic.py in nonzero(self)
1571 raise ValueError("The truth value of a {0} is ambiguous. "
1572 "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
-> 1573 .format(self.class.name))
1574
1575 bool = nonzero
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
I've managed to create a python function which takes a QQE indicator from TradingView.
The input is a Pandas.DataFrame which needs to have the column 'Close' that contains the Close price of the candles.
You can ofcourse change the input to fit your own parameters and needs.
def QQE(_candles):
#https://www.tradingview.com/script/tJ6vtBBe-QQE/
Close = _candles.Close
Fast=2.6180
Slow=4.2360
RSI=14
SF=2
def WiMA(src, length):
MA_s = [0]
for i, x in enumerate(src):
MA_s.append( (x + (MA_s[i] * (length-1)))/length )
return MA_s
def crossovers(p1,p2):
a = []
for i in range(1,min(len(p1),len(p2))):
if p1[i] < p2[i] and not p1[i-1] < p2[i-1]:
a.append(True)
elif p1[i] > p2[i] and not p1[i-1] > p2[i-1]:
a.append(True)
else:
a.append(False)
return a
RSIndex = ta.ema(ta.rsi(Close, RSI, fillna=0), SF, fillna=0)
TR = [0]
for i in range(1, len(Close)):
TH = RSIndex[i-1] if RSIndex[i-1] > RSIndex[i] else RSIndex[i]
TL = RSIndex[i-1] if RSIndex[i-1] < RSIndex[i] else RSIndex[i]
TR.append(TH - TL)
AtrRsi= WiMA(TR, 14)
SmoothedAtrRsi= WiMA(AtrRsi, 14)
# FastQQE
DeltaFastAtrRsi = [x*Fast for x in SmoothedAtrRsi]
newlongband = [x - i for x, i in zip(RSIndex,DeltaFastAtrRsi)]
longband = [0]
for i in range(1,len(RSIndex)):
if RSIndex[i-1] > longband[i-1] and RSIndex[i] > longband[i-1]:
longband.append(max(longband[i-1],newlongband[i]))
else:
longband.append(newlongband[i])
newshortband = [x + i for x, i in zip(RSIndex,DeltaFastAtrRsi)]
shortband = [0]
for i in range(1,len(RSIndex)):
if RSIndex[i-1] < shortband[i-1] and RSIndex[i] < shortband[i-1]:
shortband.append(min(shortband[i-1],newshortband[i]))
else:
shortband.append(newshortband[i])
trend = [0,0]
shortbandCross = crossovers(RSIndex, [0]+shortband)
longbandCross = crossovers([0]+longband, RSIndex)
for i in range(1,len(shortbandCross)):
if shortbandCross[i] == True:
trend.append(1)
elif longbandCross[i] == True:
trend.append(-1)
else:
trend.append(trend[i])
FastAtrRsiTL = [longband[i] if trend[i] == 1 else shortband[i] for i in range(len(trend))]
# SlowQQE
DeltaSlowAtrRsi = [x*Slow for x in SmoothedAtrRsi]
newlongband1 = [x - i for x, i in zip(RSIndex,DeltaSlowAtrRsi)]
longband1 = [0]
for i in range(1,len(RSIndex)):
if RSIndex[i-1] > longband1[i-1] and RSIndex[i] > longband1[i-1]:
longband1.append(max(longband1[i-1],newlongband1[i]))
else:
longband1.append(newlongband1[i])
newshortband1 = [x + i for x, i in zip(RSIndex,DeltaSlowAtrRsi)]
shortband1 = [0]
for i in range(1,len(RSIndex)):
if RSIndex[i-1] < shortband1[i-1] and RSIndex[i] < shortband1[i-1]:
shortband1.append(min(shortband1[i-1],newshortband1[i]))
else:
shortband1.append(newshortband1[i])
trend1 = [0,0]
shortbandCross1 = crossovers(RSIndex, [0]+shortband1)
longbandCross1 = crossovers([0]+longband1, RSIndex)
for i in range(1,len(shortbandCross1)):
if shortbandCross1[i] == True:
trend1.append(1)
elif longbandCross1[i] == True:
trend1.append(-1)
else:
trend1.append(trend1[i])
SlowAtrRsiTL = [longband1[i] if trend1[i] == 1 else shortband1[i] for i in range(len(trend1))]
return FastAtrRsiTL, SlowAtrRsiTL
I have this raw SQL statement that I would like to use for both Core and ORM:
SELECT * FROM `buffet` WHERE `roomId` = '864495034004835' AND `recordMasa` > '1514600000' AND `recordMasa` < '1514900000' AND `recordMasa` mod 10 = 0 LIMIT 0,10000000000;
Please do let me know how can I add to my existing code below to include the modulo function:
select_statement = select([Buffet]).where(and_(
Buffet.recordMasa > arguments['startDate'],
Buffet.recordMasa < arguments['endDate'],
Buffet.roomId == arguments['ident']
))
rooms = conn.execute(select_statement).fetchall()
what about the modulo operator from python?
select_statement = select([Buffet]).where(and_(
Buffet.recordMasa > arguments['startDate'],
Buffet.recordMasa < arguments['endDate'],
Buffet.roomId == arguments['ident'],
Buffet.recordMasa % 10 == 0,
))
Basically what my code does is simply update the database I have created where all the column are of 'varchar' format. My code is able to create a new entry when the time frame is '10:00-10:15'. However, when it is unable to update it when the time frame becomes '10:15-10:30' or basically any other time frame. My code is below:
import time
import MySQLdb
from MySQLdb import *
import datetime
import json
date = time.localtime()
year_mon_date_day = [date.tm_year, date.tm_mon, date.tm_mday, date.tm_wday]
column = ''
if date.tm_hour==10:
if date.tm_min<=15:
column = "10:00-10:15"
elif date.tm_min<=30:
column = "10:15-10:30"
elif date.tm_min <= 45:
column = "10:30-10:45"
elif date.tm_min <= 60:
column = "10:45-11:00"
elif date.tm_hour==11:
if date.tm_min<=15:
column = "11:00-11:15"
elif date.tm_min<=30:
column = "11:15-11:30"
elif date.tm_min <= 45:
column = "11:30-11:45"
elif date.tm_min <= 60:
column = "11:45-12:00"
elif date.tm_hour==12:
if date.tm_min<=15:
column = "12:00-12:15"
elif date.tm_min<=30:
column = "12:15-12:30"
elif date.tm_min <= 45:
column = "12:30-12:45"
elif date.tm_min <= 60:
column = "12:45-01:00"
elif date.tm_hour==13:
if date.tm_min<=15:
column = "01:00-01:15"
elif date.tm_min<=30:
column = "01:15-01:30"
elif date.tm_min <= 45:
column = "01:30-01:45"
elif date.tm_min <= 60:
column = "01:45-02:00"
else:
pass
db = MySQLdb.connect(host='localhost', user='root', passwd='4747',db='traffic_record')
cursor=db.cursor()
if column == "10:00-10:15":
query = '''INSERT INTO `traffic_record`.`RoadA` ( `Date`,`Day`,`''' + column + '''`) VALUES ('%s','%s','%s')'''
value = (year_mon_date_day,date.tm_wday, 9)
else:
query = '''UPDATE `traffic_record`.`RoadA` SET `''' + column + '''`=`%s` WHERE `Date`=''' + str(year_mon_date_day) + '''`'''
value = (3)
cursor.execute(query, value)
db.commit()
db.close()
My code gives following error when I try to run it in any other time frame other than '10:00-10:15'. I receive the following error:
/usr/bin/python2.7 /home/sparsha/PycharmProjects/MachineLearning/fill_table.py
Traceback (most recent call last):
File "/home/sparsha/PycharmProjects/MachineLearning/fill_table.py", line 83, in <module>
cursor.execute(query, value)
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 187, in execute
query = query % tuple([db.literal(item) for item in args])
TypeError: 'int' object is not iterable
Process finished with exit code 1
I am unable to solve it. Any help will be highly appreciated. Thanks.
You should set your value as an iterable:
value = (3,)
# ^
What you have (3) is an integer with a grouping parenthesis. The parenthesis does not make the integer an iterable. But adding that comma makes it a singleton tuple which is what you want.
I know multiple databases work on flask-sqlalchemy with __bind_key__.
But I don't know how to migrate those databases on alembic(flask-migrate).
Here's env.py:
from flask import current_app
config.set_main_option('sqlalchemy.url', current_app.config.get('SQLALCHEMY_BINDS')['bind_main'])
target_metadata = {
'bind_main': current_app.extensions['migrate'].db.metadata,
'bind_follower': current_app.extensions['migrate'].db.metadata,
}
How can I set follower db on target_metadata? flask-migrate doesn't care about bind databases.
Thanks.
To create a multiple database migration repository, add the --multidb argument to the init command:
$ python app.py db init --multidb
For more details please refer to flask-migrate documentation
It may be easier to scrap the old "migrations" folder and initialize the database again with the new setup, applying any customizations to the fresh directory. Most likely this would include modifying env.py or script.py.mako.
Diff init vs init --multidb
I ran a diff of the results for flask db init (i.e. single.migrations) vs flask db init --multidb (i.e. multi.migrations):
diff --suppress-common-lines single.migrations/README multi.migrations/README
1c1
< Single-database configuration for Flask.
---
> Multi-database configuration for Flask.
diff --suppress-common-lines single.migrations/env.py multi.migrations/env.py
5a6
> from sqlalchemy import MetaData
9a11,12
> USE_TWOPHASE = False
>
26a30,42
> bind_names = []
> if current_app.config.get('SQLALCHEMY_BINDS') is not None:
> bind_names = list(current_app.config['SQLALCHEMY_BINDS'].keys())
> else:
> get_bind_names = getattr(current_app.extensions['migrate'].db,
> 'bind_names', None)
> if get_bind_names:
> bind_names = get_bind_names()
> for bind in bind_names:
> context.config.set_section_option(
> bind, "sqlalchemy.url",
> str(current_app.extensions['migrate'].db.get_engine(
> bind=bind).url).replace('%', '%%'))
28a45
>
34a52,62
> def get_metadata(bind):
> """Return the metadata for a bind."""
> if bind == '':
> bind = None
> m = MetaData()
> for t in target_metadata.tables.values():
> if t.info.get('bind_key') == bind:
> t.tometadata(m)
> return m
>
>
47,50c75,76
< url = config.get_main_option("sqlalchemy.url")
< context.configure(
< url=url, target_metadata=target_metadata, literal_binds=True
< )
---
> # for the --sql use case, run migrations for each URL into
> # individual files.
52,53c78,99
< with context.begin_transaction():
< context.run_migrations()
---
> engines = {
> '': {
> 'url': context.config.get_main_option('sqlalchemy.url')
> }
> }
> for name in bind_names:
> engines[name] = rec = {}
> rec['url'] = context.config.get_section_option(name, "sqlalchemy.url")
>
> for name, rec in engines.items():
> logger.info("Migrating database %s" % (name or '<default>'))
> file_ = "%s.sql" % name
> logger.info("Writing output to %s" % file_)
> with open(file_, 'w') as buffer:
> context.configure(
> url=rec['url'],
> output_buffer=buffer,
> target_metadata=get_metadata(name),
> literal_binds=True,
> )
> with context.begin_transaction():
> context.run_migrations(engine_name=name)
70,85c116,169
< if script.upgrade_ops.is_empty():
< directives[:] = []
< logger.info('No changes in schema detected.')
<
< connectable = current_app.extensions['migrate'].db.get_engine()
<
< with connectable.connect() as connection:
< context.configure(
< connection=connection,
< target_metadata=target_metadata,
< process_revision_directives=process_revision_directives,
< **current_app.extensions['migrate'].configure_args
< )
<
< with context.begin_transaction():
< context.run_migrations()
---
> if len(script.upgrade_ops_list) >= len(bind_names) + 1:
> empty = True
> for upgrade_ops in script.upgrade_ops_list:
> if not upgrade_ops.is_empty():
> empty = False
> if empty:
> directives[:] = []
> logger.info('No changes in schema detected.')
>
> # for the direct-to-DB use case, start a transaction on all
> # engines, then run all migrations, then commit all transactions.
> engines = {
> '': {'engine': current_app.extensions['migrate'].db.get_engine()}
> }
> for name in bind_names:
> engines[name] = rec = {}
> rec['engine'] = current_app.extensions['migrate'].db.get_engine(
> bind=name)
>
> for name, rec in engines.items():
> engine = rec['engine']
> rec['connection'] = conn = engine.connect()
>
> if USE_TWOPHASE:
> rec['transaction'] = conn.begin_twophase()
> else:
> rec['transaction'] = conn.begin()
>
> try:
> for name, rec in engines.items():
> logger.info("Migrating database %s" % (name or '<default>'))
> context.configure(
> connection=rec['connection'],
> upgrade_token="%s_upgrades" % name,
> downgrade_token="%s_downgrades" % name,
> target_metadata=get_metadata(name),
> process_revision_directives=process_revision_directives,
> **current_app.extensions['migrate'].configure_args
> )
> context.run_migrations(engine_name=name)
>
> if USE_TWOPHASE:
> for rec in engines.values():
> rec['transaction'].prepare()
>
> for rec in engines.values():
> rec['transaction'].commit()
> except: # noqa: E722
> for rec in engines.values():
> rec['transaction'].rollback()
> raise
> finally:
> for rec in engines.values():
> rec['connection'].close()
diff --suppress-common-lines single.migrations/script.py.mako multi.migrations/script.py.mako
1c1,4
< """${message}
---
> <%!
> import re
>
> %>"""${message}
19,20c22,48
< def upgrade():
< ${upgrades if upgrades else "pass"}
---
> def upgrade(engine_name):
> globals()["upgrade_%s" % engine_name]()
>
>
> def downgrade(engine_name):
> globals()["downgrade_%s" % engine_name]()
>
> <%
> from flask import current_app
> bind_names = []
> if current_app.config.get('SQLALCHEMY_BINDS') is not None:
> bind_names = list(current_app.config['SQLALCHEMY_BINDS'].keys())
> else:
> get_bind_names = getattr(current_app.extensions['migrate'].db, 'bind_names', None)
> if get_bind_names:
> bind_names = get_bind_names()
> db_names = [''] + bind_names
> %>
>
> ## generate an "upgrade_<xyz>() / downgrade_<xyz>()" function
> ## for each database name in the ini file.
>
> % for db_name in db_names:
>
> def upgrade_${db_name}():
> ${context.get("%s_upgrades" % db_name, "pass")}
>
21a50,51
> def downgrade_${db_name}():
> ${context.get("%s_downgrades" % db_name, "pass")}
23,24c53
< def downgrade():
< ${downgrades if downgrades else "pass"}
---
> % endfor
Common subdirectories: single.migrations/versions and multi.migrations/versions
Note: lines prefixed with < are in the single and lines prefixed with > are found in the multiple. StackOverflow isn't the best medium to display the diff. Alternative diff -y --color=always (or another diff tool) is much easier to view.
For summary it's a few lines were removed in env.py and new lines were added to env.py script.py.mako to accommodate bind keys.
Specify New Default
To start with a new directory and retain the old in the codebase for comparison, specify the directory during the initialization:
flask init db --multidb --directory"multi.migrations"
The new directory can be specified in the program's Migrate constructor:
migrate = Migrate(directory="multi.migrations")
Likewise, in python interactive, a directory argument can be passed to the API calls:
show(directory='migrations', revision='head')
I'm working on my python script to get the list of buttons. I have got a problem with the code. When I pressed on the down arrow button of the keyboard, I get an error: TypeError: 'instancemethod' object is unsubscriptable
The error are jumping on this line:
for channel in channels[page_no*7:page_no*7+7]:
Here is the full code:
#get actioncodes from keyboard.xml
ACTION_MOVE_LEFT = 1
ACTION_MOVE_RIGHT = 2
ACTION_MOVE_UP = 3
ACTION_MOVE_DOWN = 4
CHANNELS_PER_PAGE = 7
class MyClass(xbmcgui.WindowXML):
def __new__(cls):
return super(MyClass, cls).__new__(cls, 'script-tvguide-mainmenu.xml', ADDON.getAddonInfo('path'))
def __init__(self):
self._timel = []
self.thread = None
self.buttonList=[]
self.last_page = False
def All_Channels(self):
yellow_flag = True
global __killthread__
self.getControl(4202).setLabel("0%")
try:
# DOWNLOAD THE XML SOURCE HERE
url = ADDON.getSetting('allchannel.url')
data = ''
response = urllib2.urlopen(url)
meta = response.info()
file_size = int(meta.getheaders("Content-Length")[0])
file_size_dl = 0
block_size = 2048
while True and not __killthread__:
mbuffer = response.read(block_size)
if not mbuffer:
break
file_size_dl += len(mbuffer)
data += mbuffer
state = int(file_size_dl * 10.0 / file_size)
self.getControl(4202).setLabel(str(state) + '%')
else:
if __killthread__:
raise AbortDownload('downloading')
del response
# CREATE DATABASE
profilePath = xbmc.translatePath(os.path.join('special://userdata/addon_data/script.tvguide', 'source.db'))
if os.path.exists(profilePath):
os.remove(profilePath)
con = database.connect(profilePath)
cur = con.cursor()
cur.execute('CREATE TABLE programs(channel TEXT, title TEXT, start_date TIMESTAMP, stop_date TIMESTAMP, description TEXT)')
con.commit()
# Get the loaded data
total_count = data.count('programme')/2
tv_elem = ElementTree.parse(StringIO.StringIO(data)).getroot()
cur = con.cursor()
count = 1
channels = OrderedDict()
for channel in tv_elem.findall('channel'):
channel_name = channel.find('display-name').text
for program in channel.findall('programme'):
if __killthread__:
raise AbortDownload('filling')
title = program.find('title').text
start_time = program.get("start")
stop_time = program.get("stop")
cur.execute("INSERT INTO programs(channel, title, start_date, stop_date)" + " VALUES(?, ?, ?, ?)", [channel_name, title, start_time, stop_time])
status = 10 + int(float(count)/float(total_count) * 90.0)
self.getControl(4202).setLabel(str(status) + '%')
xbmc.sleep(10)
count += 1
con.commit()
print 'Channels have been successfully stored into the database!'
self.getControl(4202).setLabel('100%')
xbmc.sleep(3000)
# Set the date and time row
current_time = time.time() # now (in seconds)
half_hour = current_time + 60*30 # now + 30 minutes
one_hour = current_time + 60*60 # now + 60 minutes
for t in [current_time,half_hour,one_hour]:
if (0 <= datetime.datetime.now().minute <= 29):
self.getControl(4204).setLabel(time.strftime("%I").lstrip('0') + ':00' + time.strftime("%p"))
self.getControl(4205).setLabel(time.strftime("%I").lstrip('0') + ':30' + time.strftime("%p"))
self.getControl(4206).setLabel(time.strftime("%I" + ":00%p",time.localtime(t)).lstrip("0"))
else:
self.getControl(4204).setLabel(time.strftime("%I").lstrip('0') + ':30' + time.strftime("%p"))
self.getControl(4205).setLabel(time.strftime("%I" + ":00%p",time.localtime(t)).lstrip("0"))
self.getControl(4206).setLabel(time.strftime("%I" + ":30%p",time.localtime(t)).lstrip("0"))
#Pull the data from the database
channelList = list()
database_path = xbmc.translatePath(os.path.join('special://userdata/addon_data/script.tvguide', 'source.db'))
if os.path.exists(database_path):
#get the channels list
cur.execute('SELECT channel FROM programs WHERE channel GROUP BY channel')
for row in cur:
channels = row[0].encode('ascii')
channelList.append(channels)
# set the channels text
for index in range(0, CHANNELS_PER_PAGE):
channel = channelList[index]
channel_index = index
if channel is not None:
pass
#self.getControl(4207 + index).setLabel(channel)
#self.button.setLabel(channel, 'font14', '0xFFFFFFFF', '0xFFFF3300', '0xFF000000')
#get the programs list
cur.execute('SELECT channel, title, start_date, stop_date FROM programs WHERE channel=?', [channel])
programList = list()
programs = cur.fetchall()
start_pos = 368 # indent for first program
for row in programs:
program = row[1].encode('ascii'), str(row[2]), str(row[3])
title = row[1].encode('ascii')
program_start_date = str(row[2])
program_end_date = str(row[3])
#convert the date formats into minutes
minutes_start = self.parseDateTimeToMinutesSinceEpoch(program_start_date)
minutes_end = self.parseDateTimeToMinutesSinceEpoch(program_end_date)
minutes_length = minutes_end - minutes_start
program_length = minutes_length
program_notification = program
programs_top_backup = 0
programs_top = 315
program_height = 34.5
program_gap = 2.5
position_start = start_pos
position_top = programs_top + channel_index * (program_height + program_gap)
if 10 <= program_length < 60:
program_width = 342.5
elif 60 <= program_length < 90:
program_width = 690
elif 90 <= program_length < 105:
program_width = 1050
elif 105 <= program_length < 120:
program_width = 1400
elif 120 <= program_length < 150:
program_width = 1750
elif 150 <= program_length < 180:
program_width = 2100
elif 180 <= program_length < 210:
program_width = 2450
elif 210 <= program_length < 240:
program_width = 2800
elif 240 <= program_length < 270:
program_width = 3150
elif 270 <= program_length < 300:
program_width = 3500
elif 300 <= program_length < 330:
program_width = 3850
elif 330 <= program_length < 360:
program_width = 4200
elif 360 <= program_length < 390:
program_width = 3250
elif 390 <= program_length < 420:
program_width = 4550
elif 420 <= program_length < 450:
program_width = 4900
elif 450 <= program_length < 480:
program_width = 5250
start_pos += program_width + 2 * program_gap
if program_width > 1:
if yellow_flag:
if program_notification:
button_nofocus = 'changelang_yellow.png'
button_focus = 'channels_bar1.png'
else:
button_nofocus = 'changelang_yellow.png'
button_focus = 'channels_bar1.png'
yellow_flag = False
text_color = '0xFF000000'
else:
if program_notification:
button_nofocus = 'channels_bar1.png'
button_focus = 'channels_yellow.png'
else:
button_nofocus = 'channels_bar1.png'
button_focus = 'channels_yellow.png'
text_color = '0xFFFFFFFF'
if program_width < 1:
program_title = ''
else:
program_title = '[B]' + title + '[/B]'
def showepg(self, channels, page_no):
self.last_page = False
self.removeControls(self.buttonList)
self.buttonList = []
page_no = 0
self.button = [[0 for x in xrange(20)] for x in xrange(20)]
self.pdata = [[dict() for x in xrange(20)] for x in xrange(20)]
row = 0
for channel in channels[page_no*7:page_no*7+7]:
#get the list of buttons in array
print channel
self.pdata[row][0]['url'] = channel['url']
self.pdata[row][0]['cname'] = xbmcgui.ControlLabel(0, self.startPos + 17 + (row * row_height), 100, row_height,channel['callSign'])
self.pdata[row][0]['cicon'] = channel['thumbnail'].replace('\\','')
self.pdata[row][0]['cimage'] = xbmcgui.ControlImage(100, self.startPos + (row * row_height), logo_width, logo_width,self.pdata[row][0]['cicon'])
self.buttonList.append(self.pdata[row][0]['cimage'])
self.buttonList.append(self.pdata[row][0]['cname'])
events = channel['events']
col = 0
coffset = 0
for event in events:
try:
self.pdata[row][col]['desc'] = '%s - %s\n%s' % (event['startTimeDisplay'], event['endTimeDisplay'], str(event['program']['description']))
#except:
self.pdata[row][col]['desc'] = ""
self.pdata[row][col]['duration'] = str(event['duration'])
self.pdata[row][col]['eptitle'] = '%s - %s : %s' % (event['startTimeDisplay'], event['endTimeDisplay'], event['eptitle'])
cwidth = int((float(event['percentWidth']) / 100) * progs_width)
self.button[row][col] = xbmcgui.ControlButton(poffset + coffset, self.startPos + (row * row_height), cwidth, row_height, event['program']['title'])
self.buttonList.append(self.button[row][col])
coffset = coffset + cwidth
col = col + 1
row = row + 1
if row == MAXIMUMROW:
break
self.addControls(self.buttonList)
if row == 0:
self.current_page = 0
self.showepg(channels, 0) # hack to display first page after last page - could be problem for empty epg
return
elif row < MAXIMUMROW:
self.last_page = True
maxrow = row
for row in range(maxrow + 1):
for col in range(20):
if self.button[row][col] == 0:
break
else:
if row < maxrow-1:
self.button[row][col].controlDown(self.button[row+1][0])
if row == maxrow-1:
if maxrow == MAXIMUMROW:
self.button[row][col].controlDown(self.button[row][col])
if col > 0:
self.button[row][col].controlLeft(self.button[row][col-1])
self.button[row][col-1].controlRight(self.button[row][col])
if row > 0:
self.button[row][col].controlUp(self.button[row-1][0])
if row == 0:
self.button[row][col].controlUp(self.button[row][col])
self.topRow = True
self.bottomRow = False
control = self.button[0][0]
self.setFocus(control)
self.updateEpg(control)
def onAction(self, action):
self.current_page = 0
self.last_page = False
if action == ACTION_MOVE_DOWN:
if allchannels_enabled:
if self.last_page:
self.current_page = 0
else:
self.current_page += 1
self.showepg(self.All_Channels, self.current_page)
return
I don't understand what the error are means. I'm trying to defined the channels to get the button control using the self.All_Channels when pressed on the down arrow button.
Do anyone know why I get an error and how to fix this?
The error means you're using [] on something that doesn't support it, this can be reproduced with (for example): None[0].
Now, the specific problem in your code appears to be:
self.showepg(self.All_Channels, self.current_page)
That this does, is pass the function self.All_Channels to the self.showepg function. this is why you're seeing instancemethod in the error, what you probably want to do, is to add parenthesis here:
self.showepg(self.All_Channels(), self.current_page)