2009-06-10 15 views
9

Sono abbastanza nuovo nell'utilizzo di database relazionali, quindi preferisco utilizzare un buon ORM per semplificare le cose. Ho passato del tempo a valutare diversi ORM Python e penso che SQLAlchemy sia ciò di cui ho bisogno. Tuttavia, sono venuto in un vicolo cieco mentale.Creazione di tabelle dinamiche e mappatura ORM in SqlAlchemy

Ho bisogno di creare un nuovo tavolo per accompagnare ogni istanza di un giocatore che creo nella tabella giocatore della mia app. Penso di sapere come creare la tabella cambiando il nome della tabella attraverso i metadati e poi chiamando la funzione create, ma non ho idea di come mapparlo a una nuova classe dinamica.

Qualcuno può darmi qualche consiglio per aiutarmi a superare il blocco del mio cervello? È possibile?

Nota: io sono aperto ad altri ORM in Python se quello che sto chiedendo è più facile da implement.Just indicarmi come :-)

+2

Creazione di tabelle dinamiche è un cattiva idea. Aggiungere una chiave a una tabella per distinguere le istanze dei giocatori è una buona idea. Cosa stai cercando di realizzare con questo business della "tavola dinamica"? –

+0

Fondamentalmente ogni giocatore ottiene la propria tabella dei punteggi per tracciare i propri punteggi nel tempo. Un giocatore può essere aggiunto in qualsiasi momento, quindi sarebbe molto difficile rintracciarlo in una tabella di punteggi gigante con tutti i giocatori in esso ... almeno per me lo fa. –

+3

Ovviamente, il processo di porre la domanda mi fa riflettere su una luce completamente nuova. Probabilmente potrei creare una tabella dei punteggi enorme che includa l'id del giocatore in una colonna insieme alle informazioni sul punteggio. Potrei quindi fare una query sull'id del giocatore per tirare dentro i loro punteggi. Grazie a tutti. –

risposta

20

Siamo assolutamente rovinato da SQLAlchemy.
Quanto segue viene preso direttamente da tutorial,
ed è davvero facile da configurare e funzionare.

E perché è fatto così spesso,
Mike Bayer ha reso questo ancora più facile
con il all-in-one "declarative" method.

Imposta il tuo ambiente (sto usando lo SQLite in memoria db per testare):

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

Definisci il tuo tavolo:

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

Se avete la registrazione attivata, ti guarda l'SQL che SqlAlchemy crea per te.

Definire la classe:

>>> 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) 

mappa della classe al vostro tavolo:

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

Creare un giocatore:

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

Questo è tutto, adesso avete un vostro tavolo giocatore .
Inoltre, il googlegroup di SqlAlchemy è eccezionale.
Mike Bayer è molto veloce nel rispondere alle domande.

+2

Grazie per le informazioni. Non proprio quello che stavo cercando. Stavo tentando qualcosa oltre a questo, un altro tavolo per giocatore. –

3

Può essere guardare zuppa di SQL, che è strato sopra SQLAlchemy http://www.sqlalchemy.org/trac/wiki/SqlSoup

o elisir (ancora una volta un involucro sopra sqlalchemy) http://elixir.ematia.de/trac/wiki

si può anche creare la tabella utilizzando SQL pianura, e per mappare dinamicamente usare queste librerie se già non hanno creare funzione di tabella.

o in alternativa creare una classe dinamica e mapparla ad es. frammento dal mio codice

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

dove BaseTable può essere qualsiasi classe Python che si desidera tutte le classi della tabella di ereditare da, ad esempio, tale classe base può avere qualche utilità o metodi comuni, ad es. metodi CRUD di base

class BaseTable(object): pass 

altrimenti non è necessario passare qualsiasi basi per type(...)

+0

Da dove importare BaseTable? Non riesco a trovarlo in sqlalchemy. –

+0

@Peter Hoffmann, risposta modificata. –

+0

Elixir non è stato aggiornato dal 2009 e sembra essere stato abbandonato. Non ha alcun supporto per python 2.7+. – Mike

1

è possibile utilizzare il metodo dichiarativo per le tabelle che creano dinamicamente nel database

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

forse non ho ben capito quello che vuoi, ma questa ricetta creano colonna identici in diversi __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

Problemi correlati