Создание динамической таблицы и отображение ORM в SqlAlchemy

Я довольно новичок в использовании реляционных баз данных, поэтому я предпочитаю использовать хороший ORM для упрощения вещей. Я потратил время на оценку различных Python ORMs, и я думаю, что SQLAlchemy-это то, что мне нужно. Однако я зашел в ментальный тупик.

Мне нужно создать новую таблицу, чтобы идти вместе с каждым экземпляром игрок я создаю в таблице моего приложения. Я думаю, что знаю, как создать таблицу, изменив имя таблицы через метаданные, а затем вызвав функцию create, но у меня есть нет подсказки о том, как сопоставить его с новым динамическим классом.

может кто-нибудь дать мне некоторые подсказки, чтобы помочь мне пройти мой ступор? Это вообще возможно?

примечание: Я открыт для других ORMs в Python, если то, что я прошу, легче реализовать.Просто покажите мне, как : -)

5 ответов


мы абсолютно испорчены SqlAlchemy.
То, что следует ниже, с учебник,
и действительно легко настроить и получить работу.

и потому, что это делается так часто,
Майк Байер сделал это еще проще
с все-в-одном "декларативный" способ.

настройте свою среду (я использую SQLite в памяти db для тестирования):

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

определить таблица:

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

если у вас включен вход в систему, вы увидите SQL, который SQLAlchemy создает для вас.

определить свой класс:

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

сопоставьте класс с таблицей:

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

создать игрока:

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

вот и все, теперь у вас есть таблица игроков.
Кроме того, SQLAlchemy googlegroup великолепна.
Майк Байер очень быстро отвечает на вопросы.


может посмотреть SQLSoup, который является слоем над SQLAlchemy.

вы также можете создавать таблицы с помощью простого SQL и динамически сопоставлять эти библиотеки, если у них уже нет функции create table.

или альтернативно создайте динамический класс и сопоставьте его:

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

где BaseTable может быть любым классом Python, от которого вы хотите наследовать все ваши классы таблиц, например, такие Base класс может иметь некоторые утилиты или общие методы, например, основные методы CRUD:

class BaseTable(object): pass

в противном случае вам не нужно передавать какие-либо базы в type(...).


вы можете использовать декларативный метод для динамического создания таблиц в 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

Я столкнулся с той же проблемой, когда пытался автоматизировать простые задачи CRUD с помощью SQLAlchemy. Вот простое объяснение и некоторый код:http://www.devx.com/dbzone/Article/42015


возможно, я не совсем понял, что вы хотите, но этот рецепт создает идентичный столбец в другом __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()

информация в Примере sqlalchemy