PythonのDjangoの枠組みの中でSQLAlchemyを使ってデータベースの教程を操作します。

12367 ワード

零、SQLAlchemyは何ですか?
SQLAlchemyの公式サイトに紹介文が書いてあります。
SQLAlchemy is the Python SQL toolkit and Object Relationl Mapper that gives
application developers the full power and flexibility of SQL.
SQLAlchemyは非常に強力なORMとデータベースツールですが、膨大なドキュメントと複雑な機能はいつも多くの人に恐怖を与えます。DjangoのORMは比較的簡単で実用的だと感じる人が多いです。
実は、SQLAlchemyもそんなに複雑ではありません。それを使っているだけでは比較的高級な機能は実はDjango ORMを使うより複雑ではありません。その豊富な機能はもっと複雑な問題に遭遇した時に対応できるようになります。
文章を書く主な目的は:
  • SQLAlchemy ORMとDjango ORMの主な使用方法を比較することにより、Djangoユーザーが迅速にSQLAlchemyという強力なツールを理解し、簡単に直観できるようにする。
  • はSQLAlchemyの具体的な技術の細い点に影響しないで、Engine接続池、Sessionの具体的な仕事の原理などを含みます。
    SQLAlchemyはDjango内に建設されたORMに対して、いくつかの非常に明らかな利点がある:
  • は独立して使用することができ、Pythonを使用するプロジェクトはいずれもデータベース
  • を操作するために使用することができます。
  • は、元のDBAPIを直接使用することと比較して、非常に豊富な特性を提供しています。接続池、aut-mapなど
  • はもっと下のSQL抽象言語を提供しています。元のsqlで解決できる問題は基本的にSQLAlchemyで解決できます。
  • 次に私達は日常のデータベース操作についてDjango ORMとSQLAlchemyを比較します。
  • 文で使用されているSQLAlchemyのバージョンは0.9.8です。
    一、Django VS SQLAlchemy
    SQLAlchemyのインストール:
    
     wget http://peak.telecommunity.com/dist/ez_setup.py
     python ez_setup.py
     sudo easy_install sqlalchemy
     sudo easy_install ipython
    
    1.データテーブルの作成
    まず、私たちはまずいくつかの表を作る必要があります。
    (1)Django
    Djangoで表を作るなら、models.pyであなたのデータタイプを定義します。
    
    from django.db import models
    
    class Game(models.Model):
     ... ...
    
    class GameCompany(models.Model):
     ... ...
    
    
    文章は経験のあるDjangoユーザー向けなので、ここでは詳細な定義コードは書かれていません。Modelを定義してから、私たちはsettings.pyのDATABASESに接続するデータベースアドレスを設定します。最後に、syncdbを使用してデータベーステーブルの作成を完了します。
    (2)SQLAlchemy
    SQLAlchemyでは、テーブル構造を定義するプロセスとDjangoは類似している:
    
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, Date
    from sqlalchemy.orm import relationship, backref
    
    Base = declarative_base()
    
    #      
    class GameCompany(Base):
     __tablename__ = 'game_company'
    
     id = Column(Integer, primary_key=True)
     name = Column(String(200), nullable=False)
     country = Column(String(50))
    
    
    class Game(Base):
     __tablename__ = 'game'
    
     id = Column(Integer, primary_key=True)
     company_id = Column(Integer, ForeignKey('game_company.id'), index=True)
     category = Column(String(10))
     name = Column(String(200), nullable=False)
     release_date = Column(Date)
    
     #  Django  ,        ,        
     #    relation   lazy                 
     company = relationship('GameCompany', backref=backref('games'))
    
    
    #            
    engine = create_engine('mysql://root:root@localhost:5379/sqlalchemy_tutorial?charset=utf8')
    #   create_all      ,          
    Base.metadata.create_all(engine)
    
    
    2.いくつかのデータを挿入する
    次に、私達は表にデータを挿入します。
    (1)Django
    Djangoでよく使われているデータの挿入方法は.save()です。
    
    nintendo = GameCompany(name="nintendo", country="Japan")
    nintendo.save()
    
    game1 = Game(
     company=nintendo,
     category="ACT",
     name="Super Mario Bros",
     release_date='1985-10-18')
    game1.save()
    
    #     create
    Game.objects.create(... ...)
    
    
    (2)SQLAlchemy
    SQLAlchemy ORMには、非常に重要なオブジェクトsessionがあり、データに対する操作はすべてsessionによって行われるので、データを挿入する前に、まずsessionを初期化します。
    
    from sqlalchemy.orm import sessionmaker
    Session = sessionmaker(bind=engine)
    session = Session()
    
    その後、データを挿入する方法もDjangoと似ています。
    
    #     
    nintendo = GameCompany(name="Nintendo", country="Japan")
    capcom = GameCompany(name="Capcom", country="Japan")
    game1 = Game(
     company=nintendo,
     category="ACT",
     name="Super Mario Bros",
     release_date='1985-10-18'
    )
    game2 = Game(
     company=capcom,
     category="ACT",
     name="Devil May Cry 3: Dante's Awakening",
     release_date="2005-03-01",
    )
    game3 = Game(
     company=nintendo,
     category="RPG",
     name="Mario & Luigi: Dream Team",
     release_date="2013-08-11",
    )
    
    #   add_all    objects session    
    session.add_all([nintendo, capcom, game1, game2])
    #      autocommit    ,      commit          
    session.commit()
    
    
    comit以外にも、sessionにはrollback()などの方法がありますが、sessionオブジェクトを単なるtranactionとして見ることができますので、内容を修正する場合は、session.com mmit()を呼び出してこれらの修正を提出してください。
    文書に行くと、より多くのsessionに関する内容が分かります。http://docs.sqlalchemy.org/en/rel_0_9/orm/session.
    二、常用操作
    1.簡単な検索
    (1)一括検索
    
    # -- Django --
    Game.objects.filter(category="RPG")
    
    # -- SQLAlchemy --
    #   filter_by  django ORM       
    session.query(Game).filter_by(category="RPG")
    session.query(Game).filter(Game.category == "RPG")
    
    
    (2)単一のオブジェクトを問い合わせる
    
    # -- Django --
    Game.objects.get(name="Super Mario Bros")
    
    # -- SQLAlchemy --
    session.query(Game).filter_by(name="Super Mario Bros").one()
    # `get_objects_or_None()`
    session.query(Game).filter_by(name="Super Mario Bros").scalar()
    
    
    Djangoには様々な種類があります。gt'、'__u u u唵「実現するためには、SQLAlchemyにおけるこのようなクエリの方がより直感的です。
    
    # -- Django --
    Game.objects.filter(release_date__gte='1999-01-01')
    #   
    Game.objects.exclude(release_date__gte='1999-01-01')
    
    # -- SQLAlchemy --
    session.query(Game).filter(Game.release_date >= '1999-01-01').count()
    #      ~    
    session.query(Game).filter(~Game.release_date >= '1999-01-01').count()
            
    
    # -- Django --
    Game.objecs.filter(company__name="Nintendo")
    
    # -- SQLAlchemy --
    session.query(Game).join(GameCompany).filter(GameCompany.name == "Nintendo")
    
    
    2.複数条件またはクエリ
    
    # -- Django --
    from django.db.models import Q
    Game.objects.filter(Q(category="RPG") | Q(category="ACT"))
    
    # -- SQLAlchemy --
    from sqlalchemy import or_
    session.query(Game).filter(or_(Game.category == "RPG", Game.category == "ACT"))
    session.query(Game).filter((Game.category == "RPG") | (Game.category == "ACT"))
    
    
    (1)inクエリ
    
    # -- Django --
    Game.objects.filter(category__in=["GAL", "ACT"])
    
    # -- SQLAlchemy --
    session.query(Game).filter(Game.category.in_(["GAL", "ACT"]))
    
    
    (2)likeクエリ
    
    # -- Django --
    Game.objects.filter(name__contains="Mario")
    
    # -- SQLAlchemy --
    session.query(Game.name.contains('Mario'))
    
    
    3.統計個数
    単純な統計総数:
    
    # -- Django --
    Game.objects.filter(category="RPG").count()
    
    # -- SQLAlchemy --
    session.query(Game).filter_by(category="RPG").count()
          
    
    # -- Django --
    from django.db.models import Count
    Game.objects.values_list('category').annotate(Count('pk')).order_by()
    
    # -- SQLAlchemy --
    from sqlalchemy import func
    session.query(Game.category, func.count(Game.category)).group_by(Game.category).all()
    
    
    4.結果の並べ替え
    クエリーの結果を並べ替える:
    
    # -- Django --
    Game.objects.all().order_by('release_date')
    Game.objects.all().order_by('-release_date')
    #      
    Game.objects.all().order_by('-release_date', 'category')
    
    # -- SQLAlchemy --
    session.query(Game).order_by(Game.release_date)
    session.query(Game).order_by(Game.release_date.desc())
    #      
    session.query(Game).order_by(Game.release_date.desc(), Game.category)
    
    
    5.データの変更
    
    # -- Django --
    game = Game.objects.get(pk=1)
    game.name = 'Super Mario Brothers'
    game.save()
    
    # -- SQLAlchemy --
    game = session.query(Game).get(1)
    game.name = 'Super Mario Brothers'
    session.commit()
    
    
    6.一括修正
    
    # -- Django --
    Game.objects.filter(category="RPG").update(category="ARPG")
    
    # -- SQLAlchemy --
    session.query(Game).filter_by(category="RPG").update({"category": "ARPG"})
    
    
    7.一括削除
    
    # -- Django --
    Game.objects.filter(category="ARPG").delete()
    
    # -- SQLAlchemy --
    session.query(Game).filter_by(category="ARPG").delete()
    
    
    三、SQLAlchemy他のいくつかの注目すべき機能
    上に簡単にいくつかのSQLAlchemy ORMとDjango ORMの使用方法を並べました。SQLAlchemyは同時にAutomap~
    もしあなたがDjangoプロジェクトを持っているなら、ORMを通じて多くのModelを作成します。この時、新しいプロジェクトが来ました。これらの表を操作したいですが、どうすればいいですか?これらのModelsをコピーしますか?オリジナルのDB-APIを使ってsqlを加えて操作しますか?
    実はSQLAlchemyのAutomapを使って、あなたの仕事がとても便利になります。新しいプロジェクトで古いデータベースに接続して、Automapを少し配置すれば、SQLAlchemyのORMを使って、他のシステムで作成した表を操作できます。
    このように:
    
    from sqlalchemy.ext.automap import automap_base
    from sqlalchemy.orm import Session
    from sqlalchemy import create_engine
    
    Base = automap_base()
    engine = create_engine("sqlite:///mydatabase.db")
    Base.prepare(engine, reflect=True)
    
    # user address    ,                  User Address 
    User = Base.classes.user
    Address = Base.classes.address
    
    
    詳細は詳細文書を参照できます。http://docs.sqlalchemy.org/en/rel_0_9/orm/extension/atomap.
    添付:DjangoとSQLAlchemyを組み合わせた例示的なデモ
    例えば、以下のgmi/db.pyコードは、gmiがDjangoプロジェクト名を作成し、プロジェクトで使用する唯一のデータベース接続のパッケージをpyとして呼び出します。
    
    # -*- coding: utf-8 -*- 
    from django.conf import settings 
    from django.core import signals 
    from django.dispatch import dispatcher 
    import sqlalchemy 
    from sqlalchemy.orm import scoped_session, sessionmaker 
    from sqlalchemy.engine.url import URL 
     
    __all__ = ['Session', 'metadata'] 
     
    def create_engine(): 
     url = URL(drivername=settings.DATABASE_ENGINE, 
        database=settings.DATABASE_NAME, 
        username=settings.DATABASE_USER, 
        password=settings.DATABASE_PASSWORD, 
        host=settings.DATABASE_HOST, 
        port=settings.DATABASE_PORT or None, 
        query = getattr(settings, 'DATABASE_OPTIONS', {}) 
        ) 
     
     options = getattr(settings, 'SQLALCHEMY_OPTIONS', {}) 
     engine = sqlalchemy.create_engine(url, **options) 
     return engine 
     
    def end_request(signal, sender): 
     Session.remove() 
     
    dispatcher.connect(receiver=end_request, 
         signal=signals.request_finished) 
     
    metadata = sqlalchemy.MetaData() 
     
    Session = scoped_session(sessionmaker(autoflush=True, 
              transactional=True, 
              bind=create_engine())) 
    
    モジュールコード
    
    from sqlalchemy.orm import * 
    from gumi.db import Session, metadata 
    some_table = Table('some_table', metadata, 
           Column('id', Integer, primary_key=True), 
           Column('some_value', String(100), nullable=False, 
           mysql_engine='InnoDB', 
           ) 
    class SomeObject(object): 
     pass 
    mapper(SomeObject, some_table) 
    
    表示コード
    
    import django.newforms as forms 
    from gumi.db import Session 
     
    class SomeForm(forms.Form): 
      # newform 
      pass 
     
    def some_action(req): 
      if req.method != "POST": 
       form = SomeForm() 
      else: 
       form = SomeForm(req.POST) 
       if form.is_valid(): 
         data = form.clean() 
         obj = SomeObject() 
         obj.some_param = data['a'] 
         obj.another_param = data['b'] 
         Session.save(obj) 
         Session.commit() 
         return HttpResponseRedirect('/') 
      return render_to_response('some/template.html')