2009-06-10 3 views
9

Ich bin relativ neu in relationalen Datenbanken, daher bevorzuge ich eine gute ORM, um die Dinge zu vereinfachen. Ich habe Zeit damit verbracht, verschiedene Python-ORMs auszuwerten, und ich denke, dass SQLAlchemy genau das ist, was ich brauche. Ich bin jedoch in eine Sackgasse geraten.Dynamische Tabellenerstellung und ORM-Mapping in SqlAlchemy

Ich muss eine neue Tabelle erstellen, die mit jeder Instanz eines Players verknüpft ist, den ich in der Player-Tabelle meiner App erstellt habe. Ich denke, ich weiß, wie man die Tabelle erstellt, indem ich den Namen der Tabelle durch die Metadaten ändere und dann die create-Funktion aufruft, aber ich habe keine Ahnung, wie man sie einer neuen dynamischen Klasse zuordnen kann.

Kann mir jemand ein paar Tipps geben, die mir helfen, mein Gehirn einzufrieren? Ist das überhaupt möglich?

Hinweis: Ich bin offen für andere ORMs in Python, wenn, was ich frage leichter implement.Just ist mir zeigen, wie :-)

+2

Erstellen von dynamischen Tabellen ist ein schlechte Idee. Das Hinzufügen eines Schlüssels zu einer Tabelle, um Instanzen von Spielern zu unterscheiden, ist eine gute Idee. Was versuchen Sie mit diesem "dynamischen Tischgeschäft" zu erreichen? –

+0

Grundsätzlich erhält jeder Spieler seine eigene Scores-Tabelle, um seine Scores im Laufe der Zeit zu verfolgen. Ein Spieler könnte zu einem beliebigen Zeitpunkt hinzugefügt werden, so dass es sehr schwer wäre, ihn in einer riesigen Punktetabelle mit allen Spielern zu verfolgen ... zumindest für mich. –

+3

Natürlich bringt mich der Prozess, die Frage zu stellen, in einem ganz neuen Licht darüber nachzudenken. Ich könnte wahrscheinlich eine riesige Punktetabelle erstellen, die die ID des Spielers in einer Spalte zusammen mit ihren Punktzahl-Informationen enthält. Ich könnte dann die Spieler-ID abfragen, um ihre Punktzahlen zu erhalten. Danke an alle. –

Antwort

20

Wir sind absolut von sqlalchemy verdorben.
Was folgt unten ist direkt aus der tutorial,
genommen und ist wirklich einfach einzurichten und zu arbeiten.

Und weil es so oft getan wird,
Mike Bayer hat dies noch einfacher
mit dem all-in-one "declarative" method.

Richten Sie Ihre Umgebung (ich bin mit dem SQLite In-Memory-db zu testen):

>>> from sqlalchemy import create_engine 
>>> engine = create_engine('sqlite:///:memory:', echo=True) 
>>> from sqlalchemy import Table, Column, Integer, String, MetaData 
>>> metadata = MetaData() 

Definieren Sie Ihre Tabelle:

>>> players_table = Table('players', metadata, 
... Column('id', Integer, primary_key=True), 
... Column('name', String), 
... Column('score', Integer) 
...) 
>>> metadata.create_all(engine) # create the table 

Wenn Sie die Protokollierung eingeschaltet haben, werden Sie Sehen Sie sich das SQL an, das SqlAlchemy für Sie erstellt.

Definieren Sie Ihre Klasse:

>>> class Player(object): 
...  def __init__(self, name, score): 
...   self.name = name 
...   self.score = score 
... 
...  def __repr__(self): 
...  return "<Player('%s','%s')>" % (self.name, self.score) 

Ordnen Sie die Klasse auf den Tisch:

>>> from sqlalchemy.orm import mapper 
>>> mapper(Player, players_table) 
<Mapper at 0x...; Player> 

erstellen Spieler:

>>> a_player = Player('monty', 0) 
>>> a_player.name 
'monty' 
>>> a_player.score 
0 

Das ist es, Sie haben jetzt einen Ihrer Spieler-Tabelle .
Auch die SqlAlchemy googlegroup ist großartig.
Mike Bayer ist sehr schnell auf Fragen zu beantworten.

+2

Danke für die Info. Nicht ganz, wonach ich gesucht habe. Ich habe etwas darüber hinaus versucht, einen anderen Tisch pro Spieler. –

3

bei SQL-Suppe zu sehen sein, die sqlalchemy Schicht vorbei ist http://www.sqlalchemy.org/trac/wiki/SqlSoup

oder Elixier (wieder ein Wrapper über sqlalchemy) http://elixir.ematia.de/trac/wiki

Sie Tabelle mit Klar sQL auch erstellen können, und zur Karte dynamisch diese libs verwenden, wenn sie schon nicht schaffen Tabellenfunktion haben.

oder alternativ eine dynamische Klasse erstellen und diese z. Ausschnitt aus meinem eigenen Code

tableClass = type(str(table.fullname), (BaseTable.BaseTable,), {}) 
mapper(tableClass, table) 

wo BaseTable jede Python-Klasse sein, die Sie alle Klassen aus erben Tisch wollen, zum Beispiel Eine solche Basisklasse kann einige nützliche oder gebräuchliche Methoden aufweisen, z. Grund CRUD Methoden

class BaseTable(object): pass 

sonst brauchen passieren Sie keine Basen type(...)

+0

Woher soll ich BaseTable importieren? Ich kann es nicht in sqlalchemy finden. –

+0

@Peter Hoffmann, bearbeitete Antwort. –

+0

Elixir wurde seit 2009 nicht aktualisiert und scheint aufgegeben worden zu sein. Es hat keine Unterstützung für Python 2.7+. – Mike

1

können Sie deklarative Verfahren zum dynamischen Erstellen von Tabellen in der Datenbank verwenden

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey 


Base = declarative_base() 

class Language(Base): 
    __tablename__ = 'languages' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(20)) 
    extension = Column(String(20)) 

    def __init__(self, name, extension): 
     self.name = name 
     self.extension = extension 
0

vielleicht habe ich nicht ganz verstanden, was Sie wollen, aber das Rezept erstellen identische Spalte in verschiedenen __tablename__

class TBase(object): 
    """Base class is a 'mixin'. 
    Guidelines for declarative mixins is at: 

    http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#mixin-classes 

    """ 
    id = Column(Integer, primary_key=True) 
    data = Column(String(50)) 

    def __repr__(self): 
     return "%s(data=%r)" % (
      self.__class__.__name__, self.data 
     ) 

class T1Foo(TBase, Base): 
    __tablename__ = 't1' 

class T2Foo(TBase, Base): 
    __tablename__ = 't2' 

engine = create_engine('sqlite:///foo.db', echo=True) 

Base.metadata.create_all(engine) 

sess = sessionmaker(engine)() 

sess.add_all([T1Foo(data='t1'), T1Foo(data='t2'), T2Foo(data='t3'), 
     T1Foo(data='t4')]) 

print sess.query(T1Foo).all() 
print sess.query(T2Foo).all() 
sess.commit() 

info in example sqlalchemy