python - SQLAlchemy 正确的模型定义和选择/插入

标签 python mysql sql database sqlalchemy

我在使用 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 的记录,因此它应该返回结果!

如果我按如下方式设置模型/表格并使用“选择”命令(如下所示),则可以:

#!/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

但是如果我遵循与“选择插入”类似的语法,则这不起作用:

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

问题: 有人可以推荐哪种创建模型的风格是正确/最好的吗?

有人可以澄清推荐模型的插入、更新、选择语法吗?

您可以推荐一个简洁明了的教程吗?我一直在浏览 SQLAlchemy 文档,它确实令人困惑——我找到了以上述两种方式设置模型的示例,但还没有找到任何以简单且一致的方式“端到端”的教程。

谢谢。

最佳答案

您是否故意不使用 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)

关于python - SQLAlchemy 正确的模型定义和选择/插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25967380/

相关文章:

python - Pandas:包含元组的熔化列

php - 通过PHP在数据库中插入度数符号

php - 选择具有多个值的记录并枚举它们

MySQL 多个 LIKE 条件不起作用

python - SQLAlchemy 中的右外连接

mysql - SQL 错误 1064 语法

python - 将 argparse 别名解析回原始命令

python - 确保只运行一个类的一个实例

python - 如何构建具有滚动总计的 Python 函数?

mysql - Rails 中的 SQL-IN 操作符多次出现相同的 ID