2014-09-22 69 views
0

我有麻煩與SQL鍊金術既建立模型和選擇/插入SQLAlchemy的適當的模型定義和選擇/插入

如果我設置的模型如下,並在項目插入表,它的工作原理:

#!/usr/bin/python 

import pymysql 
import sqlalchemy 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import * 
from sqlalchemy.orm import sessionmaker 
from sqlalchemy.sql import select 

engine = sqlalchemy.create_engine('mysql+pymysql://[email protected]/music?charset=utf8&use_unicode=0', pool_recycle=3600) 
connection = engine.connect() 

Base = declarative_base(bind=engine) 
Base 

metadata = MetaData() 

directory = Table('directory', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('size', Integer), 
    Column('name', String, unique=True), 
    ) 

words = Table('words', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('source', Integer, ForeignKey('directory.id')), 
    Column('words', String), 
    ) 

ratios = Table('ratios', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('source', Integer, ForeignKey('directory.id')), 
    Column('target', Integer, ForeignKey('directory.id')), 
    Column('ratio', Integer), 
    ) 

metadata.create_all(engine) 

# --------------------------------------------------------------------- 
# Execute Insert 
# --------------------------------------------------------------------- 

i = words.insert().values(words='jack', source=1) 
result = connection.execute(i) 

不過,如果我使用上述模型,並嘗試使用記錄的ID選擇(如下命令),我沒有得到任何結果:

s = directory.select().where(id == 1) 
result = connection.execute(s) 

for r in result: 
    print r 

表確實有帶有該ID的記錄,所以它應該返回結果!

如果不是我設置的模型/表如下,使用選擇命令(如下),這個工程:

#!/usr/bin/python 

import pymysql 
import sqlalchemy 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import * 
from sqlalchemy import UniqueConstraint 

engine = sqlalchemy.create_engine('mysql+pymysql://[email protected]/music?charset=utf8&use_unicode=0', pool_recycle=3600) 
connection = engine.connect() 


Base = declarative_base(bind=engine) 
Base 

class Directory(Base): 
    __tablename__ = "directory" 
    id = Column(Integer, primary_key=True) 
    name = Column(String(767), unique=True) 
    size = Column(Integer) 

class Words(Base): 
    __tablename__ = "words" 
    id = Column(Integer, primary_key=True) 
    source = Column(Integer, ForeignKey('directory.id')) 
    words = Column(String(1500)) 

class Ratios(Base): 
    __tablename__ = "ratios" 
    id = Column(Integer, primary_key=True) 
    source = Column(Integer, ForeignKey('directory.id')) 
    target = Column(Integer, ForeignKey('directory.id')) 
    ratio = Column(Integer) 


class Rename(Base): 
    __tablename__ = "rename" 
    id = Column(Integer, primary_key=True) 
    source = Column(Integer, ForeignKey('directory.id')) 
    name = Column(String(1500)) 


Base.metadata.create_all() 

# --------------------------------------------------------------------- 
# Execute Select 
# --------------------------------------------------------------------- 

s = select([Directory]).where(Directory.id == 1) 
result = connection.execute(s) 

for r in result: 
    print r 

不過,如果我遵循類似的語法選擇一個插入,這並未」將不起作用:

i = insert([Words]).values(source=1, words=out) 
connection.execute(i) 

問題: 有人可以推薦創建模型的哪種風格是正確的/最佳?

有人可以澄清插入,更新,選擇推薦的模型的語法?

有沒有一個教程,你可以建議,簡潔明瞭?我一直在瀏覽SQLAlchemy文檔,這真的讓人感到困惑 - 我發現了以上兩種方式設置模型的示例,但沒有找到任何以直觀和一致的方式「端對端」的教程。

謝謝。

回答

0

我得到了以下的工作,雖然我不知道這是做的最好的方式:

#!/usr/bin/python 

import pymysql 
import sqlalchemy 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import * 
from sqlalchemy.sql import select 

engine = sqlalchemy.create_engine('mysql+pymysql://[email protected]/music?charset=utf8&use_unicode=0', pool_recycle=3600) 
connection = engine.connect() 

Base = declarative_base(bind=engine) 
Base 

metadata = MetaData() 


directory = Table('directory', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('size', Integer), 
    Column('name', String, unique=True), 
    ) 

words = Table('words', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('source', Integer, ForeignKey('directory.id')), 
    Column('wordlist', String), 
    ) 

ratios = Table('ratios', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('source', Integer, ForeignKey('directory.id')), 
    Column('target', Integer, ForeignKey('directory.id')), 
    Column('ratio', Integer), 
    ) 

metadata.create_all(engine) 


# --------------------------------------------------------------------- 
# WORKING EXAMPLES 
# --------------------------------------------------------------------- 

# SELECT 
# s = select([Directory]).where(Directory.name.like("%\smeta%")) 

s = directory.select(directory.c.id==1) 
rs = connection.execute(s) 

for r in rs: 
    print r 

# INSERT 
i = words.insert().values(source=1, wordlist='blah') 
rsi = connection.execute(i) 
2

你是故意儘量不使用ORM?如果沒有,請查看comprehensive ORM tutorial

下面是一個使用ORM你有選擇,插入對象和更新示例的工作示例:

import sqlalchemy 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import * 
from sqlalchemy import orm 

engine = sqlalchemy.create_engine('sqlite://') 
connection = engine.connect() 


Base = declarative_base() 


class Directory(Base): 
    __tablename__ = "directory" 
    id = Column(Integer, primary_key=True) 
    name = Column(String(767), unique=True) 
    size = Column(Integer) 

    def __repr__(self): 
     return (
      "Directory(id={self.id}, name={self.name}, size={self.size}" 
      .format(self=self)) 


class Words(Base): 
    __tablename__ = "words" 
    id = Column(Integer, primary_key=True) 
    source = Column(Integer, ForeignKey('directory.id')) 
    directory = orm.relationship('Directory', backref='words') 
    words = Column(String(1500)) 

    def __repr__(self): 
     return (
      "Words(id={self.id}, source={self.source}, words={self.words}" 
      .format(self=self)) 


class Ratios(Base): 
    __tablename__ = "ratios" 
    id = Column(Integer, primary_key=True) 
    source = Column(Integer, ForeignKey('directory.id')) 
    target = Column(Integer, ForeignKey('directory.id')) 
    ratio = Column(Integer) 


class Rename(Base): 
    __tablename__ = "rename" 
    id = Column(Integer, primary_key=True) 
    source = Column(Integer, ForeignKey('directory.id')) 
    name = Column(String(1500)) 


def select_objs(session): 
    # 
    # Select examples 
    # 
    print 'Retrieving objects -----------------' 
    word = session.query(Words).filter(Words.id == 1).first() 
    print word 
    print 'Access the directory via a relationship!' 
    print word.directory 
    print '---------------------------' 


if __name__ == '__main__': 
    engine = create_engine('sqlite://', echo=True) 
    Session = orm.sessionmaker() 
    Session.configure(bind=engine) 
    Base.metadata.bind = engine 
    Base.metadata.create_all() 

    session = Session() 

    # 
    # Insert some objects 
    # 

    dir1 = Directory(id=1, name='Some Dir', size=10) 
    session.add(dir1) 
    # Note because of the relationship configuration and the fact that dir1 
    # is already in the session, word doesn't have to be added 
    # (no harm in doing so though) 
    word = Words(id=1, directory=dir1, words='Some words!') 
    session.flush() 

    select_objs(session) 

    # 
    # Update them 
    # 

    # Update via ORM 
    word.words = 'Some new words!' 
    # update via query 
    (
     session.query(Directory) 
     .filter(Directory.id == 1) 
     .update({"name": "A new directory name!"})) 

    # Prove they're updated: flush session, expunge existing objects 
    session.flush() 
    session.expunge(word) 

    select_objs(session)