prob mit ORM marke eigenbau

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

Montag 20. August 2007, 01:36

ich schreib mir grad ein eigenes ORM dings fuer sql->python
allerdings krieg ich wenn ich die spalte eines meiner objekte mit ``__getitem__`` beantragen will den spaltenamen zurueckgegeben, statt den dazugehoerigen wert. Das passiert auch bei nich vorhandenen spaltennamen
warum?


Code: Alles auswählen

#
#ein orm
#noch laengst nit fertig
#
#die erste spalte einer tabelle muss die primary key sein!!
#

#import cherrypy as ch
import sqlite3

conn = sqlite3.connect(':memory:')
def debug():
	while True:
		print eval(raw_input('>>>'))

#class cursor:
#	@staticmethod
#	def execute(*args):
#		print args


def cursor2result_objects(find, cursor):
	return [find(i[0]) for i in cursor.fetchall()] #die methode find wird erst in der methode fusion "hinzugefuegt"
def cursor2plain(cursor):
	return cursor.fetchone()[0]

class BasicSQLQueries(object):
	def __init__(self, primary_key_name, table_name):
		self.primary_key = primary_key_name
		self.table_name = table_name

	def exe(self, *args):
		query = args[0].replace('*table*', self.table_name).replace('*primary_key*', self.primary_key)
		print 'EXECUTING:', query, args[1:]
		cursor = conn.cursor() #conn muss vorgegeben sein
		cursor.execute(query, args[1:])
		return cursor

	def all(self):
		return cursor2result_objects(cursor=self.exe("SELECT *primary_key* FROM *table*"), find=self.find)
		
class BasicSQLResult(object):
	def __init__(self, QueryObject, primary_key, create):
		self.QueryObject = QueryObject
		self.primary_key = primary_key
		if create:
			self.QueryObject.exe('INSERT INTO *table* (*primary_key*) VALUES (?)', self.primary_key)
	def __getitem__(self, item):
		return cursor2plain(self.QueryObject.exe('SELECT ? FROM *table* WHERE *primary_key*=?', item, self.primary_key))
	def __setitem__(self, item, value):
		return self.update(**{item: value})
		#KLAPPT NICH self.QueryObject.exe('UPDATE *table* SET ? = ? WHERE *primary_key* = ?', item, value, self.primary_key)
	def update(self, **data):
		arg = data.values()
		arg.append(self.primary_key)
		self.QueryObject.exe('UPDATE *table* SET ' + ''.join([key + ' = ?, ' for key in data])[:-2] + ' WHERE *primary_key*=?', *arg)# why is foo(1, *t, 6) invalid?


		
def fusion(QueryObject, ResultClass):
	class Tmp(QueryObject):
		def __init__(self):
			QueryObject.__init__(self)
		def create(self, primary_key_val):
			return ResultClass(QueryObject=self, primary_key=primary_key_val, create=True)
		def find(self, primary_key_val):#exactly like create but did not create the row
			return ResultClass(QueryObject=self, primary_key=primary_key_val, create=False)
	return Tmp()

#==========================TEST================		


conn.cursor().execute('''CREATE TABLE users
(nickname char(50),
firstname char(50),
lastname char(50),
age int)''')
class UsersResult(BasicSQLResult):
	def __init__(self, **kw):
		BasicSQLResult.__init__(self, **kw)
	def write_post(self, text):
		post = Posts.create('foo goes bike')
		post['text'] = text
class UsersQueries(BasicSQLQueries):
	def __init__(self):
		BasicSQLQueries.__init__(self, primary_key_name='nickname', table_name='users')
	def bla(self):
		self.exe('FROM users do bullshit AND FUCK SQL')
Users = fusion(UsersQueries, UsersResult)



horst = Users.create('Horst')
horst['lastname'] = 'Allendorf'

a_user = Users.all()[0]
print a_user.QueryObject.exe('SELECT * FROM *table* where *primary_key*=?', a_user.primary_key).fetchone() #hat funktional kein sinn, gibt aber ein guten einblick

print horst['lastname'] #-> "lastname"  (WTF?)
print horst['X'] #-> "X" (und warum kein  ``OperationalError``?)


der output ist auch hilfreich:

Code: Alles auswählen

C:\Dokumente und Einstellungen\sc>"C:\Dokumente und Einstellungen\sc\Desktop\ira
e\domino.py"
EXECUTING: INSERT INTO users (nickname) VALUES (?) ('Horst',)
EXECUTING: UPDATE users SET lastname = ? WHERE nickname=? ('Allendorf', 'Horst')

EXECUTING: SELECT nickname FROM users ()
EXECUTING: SELECT * FROM users where nickname=? (u'Horst',)
(u'Horst', None, u'Allendorf', None)
EXECUTING: SELECT ? FROM users WHERE nickname=? ('lastname', 'Horst')
lastname
EXECUTING: SELECT ? FROM users WHERE nickname=? ('X', 'Horst')
X

EDIT
und noch was:
wieso geht meine ueberaus komplexe ``debug`` function nicht?
cp != mv
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 20. August 2007, 09:21

Costi hat geschrieben:warum?
Die gleiche Frage habe ich mir auch gestellt: Warum? Warum noch ein ORM? Was kann dein ORM, was andere nicht können?
Ein ORM ist keine so einfache Sache, selbst wenn ein ORM jahrelang im Einsatz ist finden sich immer noch Fehler, wie das bei Djangos ORM immer wieder der Fall ist. Der Python-Markt an ORMs ist mit Djangos ORM, SQLAlchemy,SQLObject, Storm, PyDO, etc. eher übersättigt.

Übrigens, ``eval(raw_input())`` ist genau das gleiche wie ``input()``.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Montag 20. August 2007, 12:47

Ich würde dir auch raten, es stattdessen mal mit SQLAlchemy zu versuchen. Es ist super dokumentiert, hat ein gutes Tutorial und ist sogar sinnvoll in zwei Teile aufgeteilt, den ORM und die SQL Construction Language. Diese Ternnung ist sehr praktisch, wenn es zu komplizierten Datenbank-Modellen kommt, wo du lieber selber die Kontrolle haben willst, welche Statements abgesetzt werden, anstatt es den ORM machen zu lassen.
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

Montag 20. August 2007, 14:39

ich habs schon mit verschiedenen ORMs ausprobiert,
aber es kommt immer wieder zu unerwarteten fehlern
und wenn ich die implementation kenne und sie nicht so overkilling ist kann ich mehr tun als mir die haare auszureisen

ausserdem machts mir einfach spass ein ORM zu schreiben :lol:


EDIT
ich fass es nur nicht bei zeile 100,
dort wird dann wie erwartet,

Code: Alles auswählen

("SELECT ? FROM users WHERE nickname=?" ('X', 'Horst'))
an cursor.execute mitgegeben aber warum liefert mir sqlite3 dafuer den wert ``"x"`` zurueck

[/code]
cp != mv
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 20. August 2007, 15:41

Costi hat geschrieben:ich habs schon mit verschiedenen ORMs ausprobiert,
aber es kommt immer wieder zu unerwarteten fehlern
und wenn ich die implementation kenne und sie nicht so overkilling ist kann ich mehr tun als mir die haare auszureisen
Was sind "unerwartete Fehler"? Du kannst auch so mehr tun als dir die Haare auszureißen - du kannst auch SQLAlchemy nehmen und bei Problemen in #sqlalchemy fragen - die Leute sind meist sehr schnell da um Hilfe zu leisten. Zugegeben, SQLAlchemy ist nicht das simpelste ORM (mit Elixir wirds aber etwas einfacher) aber warscheinlich das solideste, was es derzeit für Python gibt.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Montag 20. August 2007, 16:25

Ich denke mal das sind keine Fehler sondern Costi bekommt in den meisten Fällen nur richtige Antworten, die er nicht versteht. Wie das "x" bei der SQL-Abfrage. Wenn man sagt man möchte ein "x" dann bekommt man halt auch eines. Platzhalter sind für Werte, nicht für Bezeichner. D.h. in diese Abfrage wird der Wert "x" hinter das ``SELECT`` gesetzt.
Costi
User
Beiträge: 544
Registriert: Donnerstag 17. August 2006, 14:21

Montag 20. August 2007, 17:50

Platzhalter sind für Werte, nicht für Bezeichner.
ahhh das ergibt sinn, jetzt klappt alles.

bin ich jetzt nachdem ich das "foreign key"- und many-to-many-dingsbums
implementiert habe etwa schon fertig??

das werden ja deutlich weniger als 200 lines werden :lol:
cp != mv
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 20. August 2007, 23:11

Costi hat geschrieben:bin ich jetzt nachdem ich das "foreign key"- und many-to-many-dingsbums
implementiert habe etwa schon fertig??

das werden ja deutlich weniger als 200 lines werden :lol:
Planst du mit TinyP2P zu konkurrieren?

Ich habe mir mal angesehen wie SQLAlchemy im Vergleich dazu abschneidet:

Code: Alles auswählen

$ wc -l `find sqlalchemy-0.4.0beta3 -regex '.*py$' -printf '%p '`
[...]
  31607 total
:roll:
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Antworten