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

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

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

Может кто-нибудь дать мне несколько советов, которые помогут мне пройти мимо моего замораживания мозга? Возможно ли это?

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

Ответ 1

Мы абсолютно испорчены SqlAlchemy.

Ниже следует следующее из tutorial,
и действительно легко настроить и начать работать.

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

Установите свою среду (я использую SQLite in-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

Что это, теперь у вас есть таблица вашего игрока.

Кроме того, googlegroup SqlAlchemy отлично.

Майк Байер очень быстро отвечает на вопросы.

Ответ 2

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

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

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

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

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

class BaseTable(object): pass

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

Ответ 3

вы можете использовать декларативный метод для динамического создания таблиц в базе данных

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

Ответ 4

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

Ответ 5

Это очень старый вопрос. В любом случае, если вы предпочитаете ORM, довольно просто сгенерировать класс таблицы с типом:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String


Base = declarative_base()

Test = type('Test', (Base,), {
    '__tablename__': 'test',
    'test_id': Column(Integer, primary_key=True, autoincrement=True),
    'fldA': Column(String),  
    ... other columns
    }
)

Base.metadata.create_all(engine)

#  passed session create with sqlalchemy
session.query(Test).all()

Делая фабрику классов, легко назначать имена классу и таблице базы данных.

Ответ 6

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