2009-06-10 43 views
9

Soy bastante nuevo en el uso de bases de datos relacionales, por lo que prefiero usar un buen ORM para simplificar las cosas. Pasé tiempo evaluando diferentes ORM de Python y creo que SQLAlchemy es lo que necesito. Sin embargo, he llegado a un callejón sin salida mental.Creación de tablas dinámicas y mapeo ORM en SqlAlchemy

Necesito crear una nueva tabla para acompañar cada instancia de un jugador que creo en la tabla de jugadores de mi aplicación. Creo que sé cómo crear la tabla cambiando el nombre de la tabla a través de los metadatos y luego llamando a la función de creación, pero no tengo idea de cómo asignarla a una nueva clase dinámica.

¿Puede alguien darme algunos consejos para ayudarme a superar mi congelamiento cerebral? ¿Esto es posible?

Nota: estoy abierto a otros ORM en Python si lo que estoy pidiendo es más fácil de implement.Just muéstrame cómo :-)

+2

Creación de tablas dinámicas es una mala idea. Agregar una clave a una tabla para distinguir instancias de jugadores es una buena idea. ¿Qué estás tratando de lograr con este negocio de "mesa dinámica"? –

+0

Básicamente, cada jugador obtiene su propia tabla de puntajes para seguir sus puntajes a lo largo del tiempo. Se podría agregar un jugador en cualquier punto en el tiempo, por lo que sería muy difícil seguirlo en una tabla de puntajes gigante con todos los jugadores en él ... al menos para mí lo es. –

+3

Por supuesto, el proceso de hacer la pregunta me hace pensar en ello bajo una luz completamente nueva. Probablemente podría crear una gran tabla de puntuaciones que incluya la identificación del jugador en una columna junto con su información de puntaje. Entonces podría hacer una consulta en la identificación del jugador para obtener sus puntajes. Gracias a todos. –

Respuesta

20

Estamos absolutamente mimados por sqlalchemy.
Lo que sigue a continuación se toma directamente de tutorial,
y es realmente fácil de configurar y poner en funcionamiento.

Y porque se hace tan a menudo,
Mike Bayer ha hecho aún más fácil
con el all-in-one "declarative" method.

Configuración de su entorno (estoy usando el SQLite en memoria db para probar):

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

Definir la tabla:

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

Si tiene activado el registro, se le vea el SQL que SqlAlchemy crea para usted.

definir la clase:

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

en el mapa los clase a su mesa:

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

Crear un jugador:

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

Eso es todo, ahora tiene una tabla de jugador .
Además, el grupo de google SqlAlchemy es genial.
Mike Bayer es muy rápido para responder preguntas.

+2

Gracias por la información. No es exactamente lo que estaba buscando. Estaba intentando algo más allá, otra mesa por jugador. –

3

Puede ser mirar a la sopa de SQL, que es la capa más sqlalchemy http://www.sqlalchemy.org/trac/wiki/SqlSoup

o elixir (de nuevo un envoltorio sobre sqlalchemy) http://elixir.ematia.de/trac/wiki

también puede crear la tabla utilizando SQL normal, y para asignar dinámicamente usar estas bibliotecas si ya no tienen función de tabla a crear.

o bien crear una clase dinámica y asignarla, p. fragmento de mi propio código

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

donde BaseTable puede ser cualquier clase de Python, que desea que todas las clases de tabla para heredan de, por ejemplo, dicha clase Base puede tener alguna utilidad o métodos comunes, p. métodos CRUD básicas

class BaseTable(object): pass 

de lo contrario no tienen por qué pasan las bases para type(...)

+0

¿De dónde importo BaseTable? No puedo encontrarlo en sqlalchemy. –

+0

@Peter Hoffmann, respuesta editada. –

+0

Elixir no se ha actualizado desde 2009 y parece haber sido abandonado. No tiene soporte para Python 2.7+. – Mike

1

puede utilizar el método declarativo para la creación de tablas de forma dinámica en la base de datos

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

tal vez yo no entendía muy bien lo que quiere, pero esta receta crean columna idénticos en diferentes __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

Cuestiones relacionadas