[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