[python] dynamicke metody
Marek Sirový
msirovy na gmail.com
Pátek Duben 25 12:07:11 CEST 2014
Dne pátek, 25. dubna 2014 1:15:55 UTC+2 Petr Messner napsal(a):
> Ahoj,
>
>
> nejzásadnější problém, který tam vidím, je zranitelnost proti SQL injection:
>
>
> http://xkcd.com/327/
>
>
>
> Místo celého Template prostě ty parametry předej do execute:
>
>
>
>
> http://initd.org/psycopg/docs/usage.html#query-parameters
>
>
>
> Doporučuji podívat se na SQLAlchemy (http://docs.sqlalchemy.org/en/latest/). Skládá se ze dvou částí: ORM a Core. Core řeší jednotnou práci s databází v Pythonu pro více typů databází (PostgreSQL, MySQL, MS SQL, Oracle). Až začneš řešit, že placeholdery v query pro parametry jsou někde "?" (např. SQLite) a jinde "%s", tak přesně s tímhle ti to pomůže. Nebo třeba connection pooling nebo introspekce. No a ORM je ORM... to je trochu víc high level přístup, nevím, jestli se o tom teď rozepisovat... Až budeš řešit, že pro dvacet tabulek tam máš vlastně dvacet skoro stejných sad SQL dotazů, že by to místo slovníků mohlo vracet objekty a jak potom volat SQL dotazy nějak automaticky při práci s těmito objekty a jak řešit různé situace s najoinovanými dalšími objekty, tak se na to podívej :)
>
>
>
>
> Máš nějaký konkrétnější dotaz nebo problém, který chceš vyřešit? Není mi úplně jasné, na co se vlastně ptáš. Ještě mě napadá, že asi budeš chtít, aby metoda _sql() vracela funkci. To uděláš takhle pomocí closure funkce:
>
>
>
>
> def _sql(self, query):
> def f(**kwargs):
>
> self._CUR.execute(query, kwargs)
> return f
>
>
> Nebo můžeš místo toho implementovat metodu __getattr__().
>
>
>
>
> Tu metodu del budeš asi muset pojmenovat jinak, protože del je klíčové slovo.
>
>
> Jinak takovému hraní fandím. Samozřejmě je to znovuvynalézání kola. Ale je to nejlepší způsob, jak zjistit, jak kolo vlastně funguje :)
>
>
>
>
> PM
>
>
> Dne 25. dubna 2014 0:23 Marek Sirový <msi... na gmail.com> napsal(a):
>
>
> Zdravim,
>
>
>
> behem studia pythonu a hrani si s Flaskem a databazemi obecne me napadla abstrakce nad sql, kterou bych si rad zkusil vytvorit, tusim, ze nejde o nic efektivniho, nebo noveho, ale nejsem programator a python mam jako konicek a toto me zajima ciste ze studijnich duvodu, rad bych vedel, jak se to da vyresit, proto prosim nevymlouvejte mi to, ale poradte cestu... Nebo ukazte kde mam chybu
>
>
>
>
>
> Predstava:
>
>
>
> mam tridu db, ktere dam jako slovnik jmeno metody a sql dotaz, tim se mi vytvori objekt s metodami, kterym bude stacit jen predavat parametry a vrati se mi data z databaze. cili melo by fungovat neco takoveho:
>
>
>
>
>
> #!/usr/bin/env python3
>
> from string import Template
>
> import psycopg2
>
>
>
>
>
> ### trida s dynamickymi metodami
>
> class db:
>
> """ test dynamickych metod
>
> """
>
>
>
> def _sql(self, _sql = None, **kwargs):
>
> """ predloha pro dynamicke funkce
>
> """
>
> query = Template(_sql).substitute(**kwargs)
>
> print(query)
>
> _self._CUR.execute( query )
>
> return _self._conn.commit()
>
>
>
>
>
> def __init__(self, SQL = None):
>
> if SQL is None:
>
> raise(KeyError("Musite definovat slovni SQL"))
>
>
>
> # DB CONNECT
>
> self._conn = psycopg2.connect("dbname=mail user=marek", cursor_factory= psycopg2.extras.DictCursor)
>
> self._CUR = self._conn.cursor()
>
>
>
> # create methods by SQL dict
>
> for _func, _sql in SQL.items():
>
> setattr(self, _func, self._sql(_sql = _sql))
>
>
>
>
>
> def close(self):
>
> return(True)
>
>
>
>
>
>
>
> if __name__ == '__main__':
>
> '''Priklad pouziti
>
> - pridam zaznam pepa
>
> - smazu zaznam pepa
>
> '''
>
> _SQLS = {
>
> 'add' : 'insert into tabulka (name, age, email) VALUES ($name, $age, $email);',
>
> 'edit' : 'update tabulka set age = $age, email = $email where name = $name;',
>
> 'del' : 'remove from tabulka where name = $name;',
>
> }
>
>
>
> data = db(_SQLS)
>
> data.add(name = 'Pepa', age = '12', email = 'pep... na gmail.fi')
>
> data.del(name = 'Pepa')
>
> data.close()
>
>
>
> Omlouvam se za nedodrzovani PEP, skutecne nejsem moc programator a obcas docela prasim v zapalu boje.
>
>
>
> Predem diky za vysvetleni, pomoc, nasmerovani...
>
> _______________________________________________
>
> Python mailing list
>
> pyt... na py.cz
>
> http://www.py.cz/mailman/listinfo/python
>
>
>
> Visit: http://www.py.cz
Ahoj,
diky za reakci, sqlalchemy znam a ORM taky, ale mam radeji ciste sql dotazy. Kazdopadne o to nejde.
Pravdepodobne jsem spatne popsal problem, me nejde o to pripojit se k databazi, me jde o to vyzkouset si napsat tu abstrakci.
Uplne konkretne, chci napsat tridu, ktera podle predaneho pole behem inicializace si vygeneruje metody dle slovniku. Nedelam to pro nic konkretniho, jen me bavi python a zkousim co vsechno jde a tim se ucim dalsi veci
#moje magicka trida
class db:
# nejaka magie
# mam slovnik:
SQL = {
'addUser' : 'insert into users (name, email) VALUES ($name, $email);',
'delUser' : 'delete from users where name = $name',
}
# provedu si inicializaci
data = db(SQL)
# a ted mam objekt data, ktery ma metodu addUser a delUser,
# pricemz kazda z nich prebira **kwargs a podle toho doplni dotaz do db.
# priklad:
data.addUser(name = 'karel', email = 'karel na email.tld')
Toto pouziti je jen priklad, ktery me napadl pro vyzkouseni, SQL injection tam samozrejme hrozi, ale o bezpecnost tu nejde, tu bych stejne resil pravdepodobne uz na formularich pomoci validace a csrf, pak urcite na db kde z kodu volam stejne jedine procedury a pohledy, Ale ted si hraju s dymanickymi metodami a chci zkusit generovat je ze slovniku. Kod uplne v prvnim prispevku je pokus, ktery nefunguje protoze sem nejpis neco spatne pochopil.
Predem diky
Další informace o konferenci Python