sqlite insert mit 3 fremdschlüsseln

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
dunkelgruen
User
Beiträge: 7
Registriert: Mittwoch 8. Oktober 2008, 19:03

Hallo Leute,

ich habe das erste mal sqlite als Datenspeicher verwendet, dass ist auch wesentlich bequemer als die vielen csv Dateien... :) Man kann sie sich mit den verschiedenen Gui-Tools sehr gut betrachten. Allerdings bereitet mir SQL Syntax noch ziemliche Probleme!

Ich stehe vor einem INSERT Befehl und in der Zeile gibt es 3 Fremdschlüssel.
Wie gehe ich vor? Ich kann doch nicht die 3 Schlüssel in den Tabellen wo sie die Primärschlüssel darstellen vorher abfragen? Wobei hier eine Abfrage wieder einen Fremdschlüssel enthalten würde... Da muss doch irgendeinen Trick geben!

Freu mich über einen Hinweis!

Grüße
dunkelgruen
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hallo dunkelgruen, willkommen im Forum,
dunkelgruen hat geschrieben:Allerdings bereitet mir SQL Syntax noch ziemliche Probleme!
Dann nutze sie nicht. ORMs sind in Python so häufig wie Sand am Meer.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
dunkelgruen
User
Beiträge: 7
Registriert: Mittwoch 8. Oktober 2008, 19:03

Hallo Leonidas,

knapp aber klar! :)
Was sind ORMs?

Falls noch jemand einen Hinweise hat: Gerne!
Denn mich hat durchaus der Ehrgeiz gepackt.

Grüße
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

dunkelgruen hat geschrieben:knapp aber klar! :)
Was sind ORMs?
Object-Relational Mapper, also Libraries die Objekte auf RDBMS-Tabellen und Datensätze abbilden, so dass man nicht selbst das SQL schreiben muss sondern komfortabel mit Objekten arbeiten kann.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
dunkelgruen
User
Beiträge: 7
Registriert: Mittwoch 8. Oktober 2008, 19:03

Hallo,

generell: Ja es ist so wie ich oben beschrieben habe. Man muss sich die Reihenfolge überlegen in der eine Datenbank gefüllt wird und man muss die Schlüssel vorab in Erfahrung bringen.

Der Leonidas hat auf die ORMs verwiesen, die können so etwas für mich im Hintergrund erledigen. Ich lerne jetzt also SQLAlchemy: Folgendes tutorial: http://rmunn.com/sqlalchemy-tutorial/tutorial.html

An einer Stelle komme ich nicht weiter, (Es ist eine Kopie aus dem Tutorial)

Code: Alles auswählen

from sqlalchemy import *

db = create_engine('sqlite:///joindemo.db')

db.echo = True

metadata = MetaData(db)

users = Table('users', metadata, autoload=True)
emails = Table('emails', metadata, autoload=True)

# These are the empty classes that will become our data classes
class User(object):
    pass
class Email(object):
    pass

usermapper = mapper(User, users)
emailmapper = mapper(Email, emails)

session = create_session()

mary = session.query(User).selectfirst(users.c.name=='Mary')
mary.age += 1

session.flush()

fred = User()
fred.name = 'Fred'
fred.age = 37

print "About to flush() without a save()..."
session.flush()  # Will *not* save Fred's data yet

session.save(fred)
print "Just called save(). Now flush() will actually do something."
session.flush()  # Now Fred's data will be saved

session.delete(fred)
session.flush()
Ich bekomme die Fehlermeldung:
Traceback (most recent call last):
File "./mapping_alchemy.py", line 18, in <module>
usermapper = mapper(User, users)
NameError: name 'mapper' is not defined
Ich habe alles hin und her probiert und weiß keine Lösung.
:?: Muss ich noch irgendwas installieren? Ich habe SQLAlchemy 0.4.xx, und Python 2.5
Das Toturial ist bezogen auf SQLalchemy 0.2 aber in dem Docs finde ich keinen unterschiedliche Syntax.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

dunkelgruen hat geschrieben:Folgendes tutorial: http://rmunn.com/sqlalchemy-tutorial/tutorial.html
Das Tutorial ist ja auch uralt (das habe ich auch dem letzten gesagt, der hier her gekommen ist und Probleme damit hatte, weil er es benutzt hat). ich weiß gar nicht, was die Leute gegen die aktuelle Dokumentation haben.

Die Lösung ist einfach. ``mapper`` was früher in dem ``sqlalchemy`` Modul drin war, ist es nun nicht mehr. Wo es ist, verrät das aktuelle ORM Tutorial.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Einfacher für Anfänger könnt SQLObject sein. Hier sind Vortragsfolien und ein Tutorial in Deutsch.

Stefan
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

sma hat geschrieben:Einfacher für Anfänger könnt SQLObject sein.
Weißt du eigentlich ob daran noch was gemacht wird? Ian hat ja vor einiger Zeit entschieden, dass er mit SQLObject 2 weitermacht. Für Anfänger interessant könnte allerdings auch Storm von Canonical sein.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Leonidas hat geschrieben:Weißt du eigentlich ob daran noch was gemacht wird?
Weiß ich leider nicht. Auf der Mailing-List ist noch ein Aktivität, aber wirklich populär wirkt es nicht. Von SQLObject 2 habe ich nichts weiter gehört. Storm, welches IMHO das schönere API im Vergleich zu SQLalchemy hat, ist wieder größer und auch nicht so toll dokumentiert. Die ML ist auch nicht gerade aktiv. Zumindest wird daran gearbeitet. Die Versionsnummer 0.13 macht allerdings nicht so richtig Mut. Die Liste der Bugs bei SQLObject ist länger als die bei Storm. Das könnte bedeuten, dass sich bei SQLObject niemand kümmert - oder das Storm einfach von niemandem (außer Canonical) benutzt wird :)

Interessant bei Storm ist, dass es ein SQLObject-kompatibles API gibt.

Stefan
dunkelgruen
User
Beiträge: 7
Registriert: Mittwoch 8. Oktober 2008, 19:03

Hallo Leonidas,

Danke für den Hinweis, mit der Version... und dem alten Tutorial... :oops:
Habe jetzt die 0.5! Inkl. 0.5 Tutorial. :)

Hallo Stefan,

Danke für die SQLObject Links.
Allerdings habe ich mich für SQLAlchemy entschieden weil das, wie du selbst schreibst deutlich agiler ausgesehen hat.

An Beide:
Nun habe ich ein UTF-8 Problem. Umlaute gehen in die SQL rein, werden korrekt dargestellt, aber ich kann keine Querys schreiben in denen Werte mit Umlauten vorkommen.

Grüße
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

dunkelgruen hat geschrieben:An Beide:
Nun habe ich ein UTF-8 Problem. Umlaute gehen in die SQL rein, werden korrekt dargestellt, aber ich kann keine Querys schreiben in denen Werte mit Umlauten vorkommen.
Stürzt der Computer dann sofort ab wenn du ein Ü tippst? Also ein wenig spezifischer müsstest du ja schon sein, wenn du Hilfe willst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
dunkelgruen
User
Beiträge: 7
Registriert: Mittwoch 8. Oktober 2008, 19:03

Hallo,

ein Beispiel:

Code: Alles auswählen

#!/usr/bin/python
#-*- coding: utf-8 -*-

import sqlalchemy
print "SQL Alchemy Version", sqlalchemy.__version__ # 0.5rc2
from sqlalchemy import * 
from sqlalchemy.orm import *
#from sqlalchemy.ext.declarative import declarative_base
#from sqlalchemy import ForeignKey
#from sqlalchemy.orm import relation, backref

engine = create_engine('sqlite:///tutorial_sqlalchemy05.sqlite', echo = True, 
															encoding="utf-8")
Session = sessionmaker(bind=engine)
session = Session()
#------------------------------------------------------------------------------
metadata = MetaData()
#Base = declarative_base()
#------------------------------------------------------------------------------
users_table = Table('users', metadata,
	Column('id', Integer, primary_key=True),
	Column('name', String),
	Column('fullname', String),
	Column('password', String))
#------------------------------------------------------------------------------
class User(object):
	def __init__(self, name, fullname, password):
		self.name = name
		self.fullname = fullname
		self.password = password

	def __repr__(self):
		return "<User('%s','%s', '%s')>" % (self.name, self.fullname, 
											self.password)
#------------------------------------------------------------------------------
mapper(User, users_table)
metadata.create_all(engine)  
#------------------------------------------------------------------------------
ed_user = User('ed', 'Ed Jones', 'edspassword')
umlaut_user = User('Mit', 'Umlaut', 'EinÖ')
session.add(ed_user)
session.add(umlaut_user)
session.commit()

query = session.query(User).filter(User.name == "Mit")
print query.all()
Bringt die Fehlermeldung:
SQL Alchemy Version 0.5.0rc2
2008-10-26 08:01:59,570 INFO sqlalchemy.engine.base.Engine.0x...0ecL PRAGMA table_info("users")
2008-10-26 08:01:59,571 INFO sqlalchemy.engine.base.Engine.0x...0ecL {}
2008-10-26 08:01:59,572 INFO sqlalchemy.engine.base.Engine.0x...0ecL
CREATE TABLE users (
id INTEGER NOT NULL,
name VARCHAR,
fullname VARCHAR,
password VARCHAR,
PRIMARY KEY (id)
)


2008-10-26 08:01:59,573 INFO sqlalchemy.engine.base.Engine.0x...0ecL {}
2008-10-26 08:01:59,579 INFO sqlalchemy.engine.base.Engine.0x...0ecL COMMIT
2008-10-26 08:01:59,585 INFO sqlalchemy.engine.base.Engine.0x...0ecL BEGIN
2008-10-26 08:01:59,587 INFO sqlalchemy.engine.base.Engine.0x...0ecL INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
2008-10-26 08:01:59,587 INFO sqlalchemy.engine.base.Engine.0x...0ecL ['ed', 'Ed Jones', 'edspassword']
2008-10-26 08:01:59,588 INFO sqlalchemy.engine.base.Engine.0x...0ecL INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
2008-10-26 08:01:59,588 INFO sqlalchemy.engine.base.Engine.0x...0ecL ['Mit', 'Umlaut', 'Ein\xc3\x96']
2008-10-26 08:01:59,589 INFO sqlalchemy.engine.base.Engine.0x...0ecL COMMIT
2008-10-26 08:01:59,594 INFO sqlalchemy.engine.base.Engine.0x...0ecL BEGIN
2008-10-26 08:01:59,596 INFO sqlalchemy.engine.base.Engine.0x...0ecL SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password
FROM users
WHERE users.name = ?
2008-10-26 08:01:59,624 INFO sqlalchemy.engine.base.Engine.0x...0ecL ['Mit']
[Traceback (most recent call last):
File "./EncodingFehler", line 46, in <module>
print query.all()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xd6' in position 26: ordinal not in range(128)

Ansonsten passiert nichts und der Rechner stürzt nicht ab... :shock:
BlackJack

Es dürfte nicht an der Abfrage liegen, sondern an der Ausgabe mit ``print``. Mach mal aus der letzten Zeile ein

Code: Alles auswählen

print repr(query.all())
dunkelgruen
User
Beiträge: 7
Registriert: Mittwoch 8. Oktober 2008, 19:03

Hallo,

nein das hilft leider nicht. Aber ist vielleicht der richtige Weg... denn wenn h die Zeilen 32/33/34 lösche (sind ja optional) dann wird die Referenz auf das Objekt (korrekt fomuliert?) ausgeliefert.

Leider ist es nicht lesbar bzw. nicht weiterzuverarbeiten.

Grüße
Sebastian
dunkelgruen
User
Beiträge: 7
Registriert: Mittwoch 8. Oktober 2008, 19:03

Ich habe die gleiche Frage einfach mal in der SQLAlchemy Mailing Liste gestellt.
Dies ist die Antwort:
use the Unicode type instead of the String type, or alternatively set
convert_unicode=True on your create_engine() call.
Jedoch gehts bei mir trotzdessen nicht.
Vielleicht bei einem von euch...

Grüße
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Dein Problem ist nicht SA sondern deine Ausgabe. Genauer: __repr__. Das muss einen String zurückgeben.


Versuchs mal mit:

Code: Alles auswählen

class User(object): 
    def __init__(self, name, fullname, password): 
        self.name = name 
        self.fullname = fullname 
        self.password = password 
    def __repr__(self): 
        return u"<User(%r, %r, %r)>" % (self.name, self.fullname, 
                                            self.password) 
BlackJack

Da würde ich jetzt noch das u" und die "spitzen Klammern" weg lassen.
Antworten