25

私はリレーショナルデータベースの使用にかなり慣れていないので、物事を単純化するために優れたORMを使用することを好みます。私はさまざまなPythonORMの評価に時間を費やしましたが、SQLAlchemyが必要だと思います。しかし、私は精神的な行き詰まりになりました。

アプリのプレーヤーテーブルで作成したプレーヤーの各インスタンスに合わせて、新しいテーブルを作成する必要があります。メタデータを使用してテーブルの名前を変更してからcreate関数を呼び出すことでテーブルを作成する方法は知っていると思いますが、新しい動的クラスにマップする方法がわかりません。

誰かが私の脳の凍結を乗り越えるのに役立ついくつかのヒントを教えてもらえますか?これも可能ですか?

注:私が求めているものが実装しやすい場合は、Pythonで他のORMを受け入れることができます。方法を教えてください:-)

4

7 に答える 7

38

私たちは SQLAlchemy に甘やかされています。
以下はチュートリアルから直接引用したもので、
セットアップと作業は非常に簡単です。

また、頻繁に行われるため
、ドキュメントは2011 年 8 月に完全な宣言型に移行しました。

環境をセットアップします (テストには SQLite インメモリ データベースを使用しています)。

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

ログを有効にしている場合は、SQLAlchemy が作成する SQL が表示されます。

クラスを定義します。

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

これで、プレーヤー テーブルができました。

于 2009-06-10T03:30:15.517 に答える
5

SQLAlchemy のレイヤーであるSQLSoupを見てください。

プレーン SQL を使用してテーブルを作成することもできます。テーブル作成関数がまだない場合は、これらのライブラリを使用して動的にマップします。

または、動的クラスを作成してマップします。

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

ここで、BaseTable は、すべてのテーブル クラスの継承元となる任意の Python クラスにすることができます。たとえば、このようなBaseクラスには、基本的な CRUD メソッドなどのユーティリティまたは一般的なメソッドが含まれる場合があります。

class BaseTable(object): pass

それ以外の場合は、ベースを に渡す必要はありませんtype(...)

于 2009-06-10T03:29:30.417 に答える
2

データベースにテーブルを動的に作成するために宣言的な方法を使用できます

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
于 2009-06-27T10:15:08.060 に答える
1

SQLAlchemy を使用して単純な CRUD タスクを自動化しようとしたときに、同じ問題に直面しました。ここに簡単な説明といくつかのコードがあります: http://www.devx.com/dbzone/Article/42015

于 2009-10-23T20:21:20.073 に答える
0

多分私はあなたが何を望んでいるのかよく理解していませんでしたが、このレシピは異なる __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

于 2013-05-09T05:10:16.610 に答える