sqlalchemy.exc.NoReferencedTableError: Could not find table

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
ska.ndal
User
Beiträge: 24
Registriert: Freitag 6. November 2009, 16:02

hallo,

ich habe heute mit sqlalchemy angefangen. hab das tutorial durchgearbeitet und jetzt eigenes zeugs geschrieben. aber jetzt häng ich schon rehct lange an einem prob fest: ich habe eine bestehende db und möchte eine many-to-many relation erstellen. wenn ich die beiden klassen mit den daten als klassen erstelle und die beziehungen in einer einfachen tabelle hab ich erstmal keine fehlermeldung. aber sobald ich das

Code: Alles auswählen

photos = relation("photo", secondary=photo_tags, backref="tags")
einfüge, dann bekomm ich immer die fehlermeldung
sqlalchemy.exc.NoReferencedTableError: Could not find table 'photos' with which to generate a foreign key
kann mir vielleicht wer sagen, was das problem ist? hänge da schon recht lange dran und komm einfach nicht zur lösung.

vielen dank, ska.ndal
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Der ganze Code wäre schon recht hilfreich.
ska.ndal
User
Beiträge: 24
Registriert: Freitag 6. November 2009, 16:02

Code: Alles auswählen

from sqlalchemy import create_engine, Table, Column, Integer, String, Text, MetaData, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relation
# from sqlalchemy.orm import backref

import time

engine = create_engine("sqlite:///photos.db", echo=True)
Base = declarative_base()
Session = sessionmaker(bind=engine)
session = Session()
metadata = MetaData()

photo_tags = Table("photo_tags", metadata, 
  Column("photo_id", Integer, ForeignKey("photos.id")),
  Column("tag_id", Integer, ForeignKey("tags.id"))
)
  
class tag(Base):
  __tablename__ = "tags"
  
  id = Column(Integer, primary_key=True)
  name = Column(Text)
  category_id = Column(Integer)
  is_category = Column(Integer)
  sort_priority = Column(Integer)
  icon = Column(Text)
  
  photos = relation("photo", secondary=photo_tags, backref="tags")
  
  def __init__(self, name, category_id=0, is_category=1, sort_priority=0, icon=""):
    self.name = name
    self.category_id = category_id
    self.is_category = is_category
    self.sort_priority = sort_priority
    self.icon = icon
  
  def __repr__(self):
    return "<Tag('%s','%s', '%s', '%s', '%s')>" % (self.name, self.category_id, self.is_category, self.sort_priority, self.icon)


class photo(Base):
  __tablename__ = "photos"
  
  id = Column(Integer, primary_key=True)
  time = Column(Integer)
  uri = Column(String)
  description  = Column(Text)
  roll_id = Column(Integer)
  default_version_id = Column(Integer)
  rating = Column(Integer)
  md5_sum = Column(Text)
  
  def __init__(self, time=0, uri="", description="", roll_id=0, default_version_id=1, rating=0, md5_sum=""):
    self.id = 0
    self.time = time
    self.uri = uri
    self.description = description
    self.roll_id = roll_id
    self.default_version_id = default_version_id
    self.rating = rating
    self.md5_sum = md5_sum
  
  def __repr__(self):
    return "<Photo('%s','%s', '%s', '%s', '%s', '%s', '%s')>" % (self.time, self.uri, self.description, self.roll_id, self.default_version_id, self.rating, self.md5_sum)
gibt es gar keinen paste-service?
Benutzeravatar
Käptn Haddock
User
Beiträge: 169
Registriert: Freitag 24. März 2006, 14:27

Deine Tabelle heist 'photos', nicht 'photo'.

Cu Uwe
---------------------------------
have a lot of fun!
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

tag und photo nutzen Base.metadata, deine photo_tags Tabelle nutzt metadata.

Der ForeignKey in der photo_id Spalte, findet natürlich in metadata nicht die photos Tabelle die in Base.metadata steckt.

EDIT: @Käptn Haddock Sollte kein Problem sein weil die Klasse photo heisst, wie auch immer dass löst die Exception nicht aus.
Benutzeravatar
Käptn Haddock
User
Beiträge: 169
Registriert: Freitag 24. März 2006, 14:27

@DasIch: Stimmt. Da muß ja die Klasse hin und nicht der Tabellenname... :oops:

Tip: Klassennamen mit einem führenden Großbuchstaben schreiben. (CamelCase oder wie das heisst ;))

CU Uwe
---------------------------------
have a lot of fun!
ska.ndal
User
Beiträge: 24
Registriert: Freitag 6. November 2009, 16:02

tag und photo nutzen Base.metadata, deine photo_tags Tabelle nutzt metadata.

Der ForeignKey in der photo_id Spalte, findet natürlich in metadata nicht die photos Tabelle die in Base.metadata steckt.
wie lös ich das dann also? dann mach ich die photo_tags auch als klasse, oder übergeb ich der statt metadata einfach Base oder wie?

das mit dem grossschreiben der klassen werd ihc machen.. das ist gut!

vielen dank
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

ska.ndal hat geschrieben:das mit dem grossschreiben der klassen werd ihc machen.. das ist gut!
PEP8 hat noch mehr zu bieten, einfach mal anschaun.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

ska.ndal hat geschrieben:wie lös ich das dann also? dann mach ich die photo_tags auch als klasse, oder übergeb ich der statt metadata einfach Base oder wie?
Übergib Base.metadata statt metadata.
Benutzeravatar
Käptn Haddock
User
Beiträge: 169
Registriert: Freitag 24. März 2006, 14:27

ska.ndal hat geschrieben:

wie lös ich das dann also?

Code: Alles auswählen

metadata = Base.metadata
oder

Code: Alles auswählen

photo_tags = Table("photo_tags", Base.metadata,
  Column("photo_id", Integer, ForeignKey("photos.id")),
  Column("tag_id", Integer, ForeignKey("tags.id"))
)
EDIT: Eventuell auch Base.metadata()... bin grad zu faul zum nachschauen ;)

Cu Uwe
---------------------------------
have a lot of fun!
ska.ndal
User
Beiträge: 24
Registriert: Freitag 6. November 2009, 16:02

ja mit Base.metadata funktioniert es..

vielen dank euch helfer_innen..
ska.ndal
User
Beiträge: 24
Registriert: Freitag 6. November 2009, 16:02

also ich kann zwar jetzt über mehrere tabellen abfragen, aber dafür nicht mehr in der einen. ich kann nicht mehr anfragen wie diese machen:

Code: Alles auswählen

session.query(photo).filter(photo.id=629).first()
ich bekomme immer die fehlermeldung:
File "<stdin>", line 1
SyntaxError: keyword can't be an expression
kapier irgendwie nicht, was das problem dabei sein soll
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

filter und order_by nehmen ein ClauseElement entgegen, kein Keyword Argument wie filter_by. Statt photo.id=629 was natürlich ein SyntaxError ist, schreibst du photo.id == 629, welches ein ClauseElement zurückliefert.
Benutzeravatar
Käptn Haddock
User
Beiträge: 169
Registriert: Freitag 24. März 2006, 14:27

ska.ndal hat geschrieben:

Code: Alles auswählen

session.query(photo).filter(photo.id=629).first()
ich bekomme immer die fehlermeldung:
File "<stdin>", line 1
SyntaxError: keyword can't be an expression
kapier irgendwie nicht, was das problem dabei sein soll

Code: Alles auswählen

photo.id==629 
Du brauchst einen Vergleich, keine Zuweisung an der Stelle AFAIR.

Gruß Uwe
---------------------------------
have a lot of fun!
ska.ndal
User
Beiträge: 24
Registriert: Freitag 6. November 2009, 16:02

ok so langsam erschliesst sich mir die sache...

ich danke euch!
Antworten