Elixir: AttributeError bei Relationship

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Hi, ich bastle gerade mit Elixir eine kleine Datenbank. Dafür würde ich gerne Strings als Primary Keys verwenden. Dabei bekomme ich eine Fehlermeldung. (den Fehler bekomme ich auch bei Integer)

Das Modul für die Sprache. Hier möchte ich als Primary Key ein Kürzel wie z.B. "de" verwenden.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*- 
from elixir import using_options, Entity, Field, Unicode, OneToMany, ManyToOne, Integer, String

class Languages(Entity):
    name = Field(Unicode(15))
    shortcut = Field(String(2), primary_key=True)
    mgname = OneToMany('MaterialGroupName')
Das Modul, in dem die Sprache eingetragen werden soll. Im Feld "language" soll dann z.B. "de" stehen

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*- 
from elixir import using_options, Entity, Field, Unicode, ManyToOne, OneToMany


class MaterialGroupName(Entity):
    name=Field(Unicode(20))
    mg = ManyToOne('MaterialGroups')
    language = ManyToOne('Languages')
Ich generiere einen Testeintrag in der Sprachtabelle

Code: Alles auswählen

# Create some Demo Data for Language
de=Languages(name=u"Deutsch", shortcut="de")
Der Fehler tritt auf, wenn jetzt einen Eintrag in der Tabelle "MaterialGroupName" anlegen will.

Code: Alles auswählen

# Create some Demo Data for MaterialGroupNames
ucname=MaterialGroupName(name=u"Mikrocontroller", language="de")
Der Fehler tritt aber nur auf, wenn ich dem Feld "language" oder dem Feld "mg" einen Wert zuweisen will. Wenn ich nur das "name" Feld angebe wird alles korrekt erstellt, bis auf die fehlende Relation


Die Fehlermeldung lautet

Code: Alles auswählen

Traceback (most recent call last):
  File "create_table.py", line 26, in <module>
    ucname=MaterialGroupName(name=u"Mikrocontroller", language="de")
  File "/usr/lib/python2.6/dist-packages/elixir/entity.py", line 718, in __call_
_
    return type.__call__(cls, *args, **kwargs)
  File "<string>", line 4, in __init__
  File "/usr/lib/pymodules/python2.6/sqlalchemy/orm/state.py", line 82, in initi
alize_instance
    return manager.events.original_init(*mixed[1:], **kwargs)
  File "/usr/lib/python2.6/dist-packages/elixir/entity.py", line 876, in __init_
_
    self.set(**kwargs)
  File "/usr/lib/python2.6/dist-packages/elixir/entity.py", line 880, in set
    setattr(self, key, value)
  File "/usr/lib/pymodules/python2.6/sqlalchemy/orm/attributes.py", line 150, in
 __set__
    self.impl.set(instance_state(instance), instance_dict(instance), value, None
)
  File "/usr/lib/pymodules/python2.6/sqlalchemy/orm/attributes.py", line 575, in
 set
    value = self.fire_replace_event(state, dict_, value, old, initiator)
  File "/usr/lib/pymodules/python2.6/sqlalchemy/orm/attributes.py", line 595, in
 fire_replace_event
    value = ext.set(state, value, previous, initiator or self)
  File "/usr/lib/pymodules/python2.6/sqlalchemy/orm/attributes.py", line 827, in
 set
    new_state,  new_dict = instance_state(child), instance_dict(child)
AttributeError: 'str' object has no attribute '_sa_instance_state'
Wobei die Fehlermeldung bei Unicode oder Integer ein entsprechendes Objekt angibt.

Die Frage ist jetzt, habe ich irgendwo einen Denkfehler oder geht da was nicht mit Elixir? Ich komme nicht dahinter.
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Auch dieses Problem hat sich soeben von selbst gelöst (ist es nicht schön? ;) )

Die Lösung ist, es muss so heißen, weil der generierte Tabellenname so heißt

Code: Alles auswählen

ucname=MaterialGroupName(name=u"Mikrocontroller", language_shortcut=u"de", mg_shortcut=u"uc")
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

burli hat geschrieben:Die Frage ist jetzt, habe ich irgendwo einen Denkfehler oder geht da was nicht mit Elixir? Ich komme nicht dahinter.
Language ist eben ein Language-Objekt und kein String, woher soll Elixir wissen wie er von dem String zum Objekt kommt?

Die Lösung ist also:

Code: Alles auswählen

de = Languages...
ucname=MaterialGroupName(name=u"Mikrocontroller", language=de)
burli
User
Beiträge: 1156
Registriert: Dienstag 9. März 2004, 18:22

Ich habe inzwischen noch eine Lösung

Code: Alles auswählen

    # Create some Demo Data for Language
    de = Languages(name=u"Deutsch", shortcut=u"de")
    en = Languages(name=u"Englisch", shortcut=u"en")

    # Create some Demo Data for material group
    Mikrocontroller     = MaterialGroups(shortcut=u"uc", parent=u"root")
    ucnamede            = Name(text=u"Mikrocontroller")
    ucnameen            = Name(text=u"Microcontroller")

    Mikrocontroller.name.append(ucnamede)
    Mikrocontroller.name.append(ucnameen)

    de.mgname.append(ucnamede)
    en.mgname.append(ucnameen)
Funktioniert natürlich nur, wenn man die Sprache in einer Variable hat bzw ein Objekt der Sprache
Antworten