我在设置模型和选择/插入
时遇到了SQL Alchemy的问题如果我按如下方式设置模型并将项目插入表中,则可以正常工作:
#!/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://root@127.0.0.1/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的记录,因此它应该返回一个结果!
如果我按如下方式设置模型/表并使用Select命令(如下所示),则可以:
#!/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://root@127.0.0.1/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
但是如果我遵循与Select for Insert类似的语法,那么这不起作用:
i = insert([Words]).values(source=1, words=out)
connection.execute(i)
问题: 有人可以推荐哪种风格的模型是正确的/最好的吗?
有人可以澄清插入,更新,选择推荐模型的语法吗?
是否有可以推荐的教程简洁明了?我一直在阅读SQLAlchemy文档并且它真的让人感到困惑 - 我找到了以上两种方式设置模型的示例,但是没有找到任何教程#34&#34 ;端至端"以一种直截了当的方式。
谢谢。
答案 0 :(得分: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)
答案 1 :(得分: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://root@127.0.0.1/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)