Original Address: https://www.cnblogs.com/mrchige/p/6389588.html
SQLAlchemy tutorial - Basics articles
I. Course Description
1.1 experimental content
This course led everyone to use SQLAlchemy connect to the MySQL database, create a blog application data tables needed, and introduced the use of a simple SQLAlchemy CURD operation and use Faker generate test data.
1.2 curriculum knowledge
- Learn to use SQLALchemy connect to the database (MySQL, SQLite, PostgreSQL), create a data table;
- Between one master data table, and many-to-many relationship and can be converted to the corresponding description SQLAlchemy;
- Master the use SQLAlchemy be CURD operations;
- Learn to use Faker generate test data
This course requires you to learn Python and MySQL have a basic grasp.
Two, ORM and SQLAlchemy Profile
ORM full name Object Relational Mapping
, translated called 对象关系映射
. Simply put, ORM will table in the database and object-oriented language classes to establish a correspondence. Thus, we have to operate a database, a table or a record in the database table can be done directly by the operator or a class instance of the class.
SQLAlchemy Python community is one of the most well-known ORM tools for the efficient design and high performance database access, to achieve a complete enterprise-level persistence model.
Next we will build experimental use SQLAlchemy and MySQL database application of a blog.
Install SQLAlchemy:
$ sudo pip install sqlalchemy
Third, create a connection
Laboratory building environment for us has been installed MySQL, but has not started before you start MySQL, we need to do some configuration, MySQL default latin1 encoded into utf8.
$ sudo vim /etc/mysql/my.cnf
Open the MySQL configuration file by the above command, add the following several configurations:
[client]
default-character-set = utf8
[mysqld] character-set-server = utf8 [mysql] default-character-set = utf8
Save and exit. Now we can start the MySQL service:
$ sudo service mysql start
Enter the following command at the command line to start MySQL:
$ mysql -uroot -p
See the contents of the above to explain our MySQL can start a normal (Note that the above does not require password input, just press Enter on the line), and we have our command:
> create database blog;
Create a file called blog
database to prepare for the following use.
In addition, we need to install a driver between Python and MySQL:
$ sudo apt-get install python-mysqldb
3.1 database connection
We create a Python file in the Code, what was the name of it as you will, where we call db.py
, write the following:
# coding: utf-8
from sqlalchemy import create_engine engine = create_engine('mysql+mysqldb://root@localhost:3306/blog') print(engine)
In the above program, we are connected by default to run 3306
MySQL port in the blog
database.
Under run this program, see the following information shows that we have a successful connection:
Table 3.2 describes the structure
To use ORM, we need to structure the data tables with ORM language to describe it. SQLAlchmey provides a Declarative system to accomplish this task. We create a users
table, for example, to see how it was with SQLAlchemy language to describe:
# coding: utf-8
from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, String, Integer engine = create_engine('mysql+mysqldb://root@localhost:3306/blog?charset=utf8') Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(64), nullable=False, index=True) password = Column(String(64), nullable=False) email = Column(String(64), nullable=False, index=True) def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.username)
We see that in User
the class, with the __tablename__
specified name in the table in MySQL. We created three basic fields, each a class Column
on behalf of a database, in Colunm
, specify some configuration of the column. Field represents the data type of the first class, we used above String
, Integer
the two most common types of other commonly used include:
Text
Boolean
SmallInteger
DateTime
nullable=False
May not be representative of this column is empty, index=True
it represents the creation of the index in the column.
Otherwise defined __repr__
in order to facilitate debugging, you can not define, but some of the details can be defined.
$ python db.py
Run the program, we look at how MySQL Table is created:
Fourth, the relationship is defined
4.1-to-many relationship
For an ordinary blog applications, users, and the article is clearly a to-many relationship, an article belongs to a user, a user can write a lot of articles, the relationship between them can be defined as:
class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(64), nullable=False, index=True) password = Column(String(64), nullable=False) email = Column(String(64), nullable=False, index=True) articles = relationship('Article') def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.username) class Article(Base): __tablename__ = 'articles' id = Column(Integer, primary_key=True) title = Column(String(255), nullable=False, index=True) content = Column(Text) user_id = Column(Integer, ForeignKey('users.id')) author = relationship('User') def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.title)
Each article has a foreign key to the users
primary key of the table id
, in User
use SQLAlchemy provided relationship
to describe the relationship. And this relationship between the user and the article is two-way, so we see the above two tables are defined relationship
.
SQLAlchemy provides backref
allows us to only need to define a relationship:
articles = relationship('Article', backref='author')
Added to this will be no longer in Article
the definition of relationship
the!
4.2 one relationship
In User
we only have to define a few fields, but usually there are many other user information, but this information may not be necessary to fill, we can put them into another UserInfo
table, so User
and UserInfo
on the formation of one Relationship. You might wonder why not one-to-many relationship in front of relationship? That's because one-to-many relationship is defined:
class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(64), nullable=False, index=True) password = Column(String(64), nullable=False) email = Column(String(64), nullable=False, index=True) articles = relationship('Article', backref='author') userinfo = relationship('UserInfo', backref='user', uselist=False) def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.username) class UserInfo(Base): __tablename__ = 'userinfos' id = Column(Integer, primary_key=True) name = Column(String(64)) qq = Column(String(11)) phone = Column(String(11)) link = Column(String(64)) user_id = Column(Integer, ForeignKey('users.id'))
Many define methods and the same, but you need to add userlist=False
.
4.3-many relationship
Again usually have a blog classification, several labels. Is one-many relationship between the label and blog. Many relationship can not be defined directly, need to be broken down into two one-to-many relationship, therefore, we need an extra table to assist with:
article_tag = Table(
'article_tag', Base.metadata,
Column('article_id', Integer, ForeignKey('articles.id')), Column('tag_id', Integer, ForeignKey('tags.id')) ) class Tag(Base): __tablename__ = 'tags' id = Column(Integer, primary_key=True) name = Column(String(64), nullable=False, index=True) def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.name)
4.4 is mapped to the data
Table has been described well, use the following command at the end of the file create the corresponding table in the database of our connections:
if __name__ == '__main__':
Base.metadata.create_all(engine)
Look into the MySQL:
All tables has been created!
Five simple CURD
When you want to call your friends, you have to use mobile phone to call his number in order to establish a session? Similarly, you want to talk to and MySQL have to first establish a session with SQLAlchemy:
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
You can sessionmaker
think of a cell phone, engine
as MySQL number, dial the "number" we created a Session class, the following can be instances of this class by pleasant conversation with the MySQL!
5.1 Create
If you played LOL, I think you must know Faker. In the world of Python, Faker is used to generate a library of false data. Install it:
$ sudo pip install faker
Faker below in conjunction with the library to create some test data:
faker = Factory.create()
Session = sessionmaker(bind=engine)
session = Session()
faker_users = [User(
username=faker.name(),
password=faker.word(),
email=faker.email(),
) for i in range(10)] session.add_all(faker_users) faker_categories = [Category(name=faker.word()) for i in range(5)] session.add_all(faker_categories) faker_tags= [Tag(name=faker.word()) for i in range(20)] session.add_all(faker_tags) for i in range(100): article = Article( title=faker.sentence(), content=' '.join(faker.sentences(nb=random.randint(10, 20))), author=random.choice(faker_users), category=random.choice(faker_categories) ) for tag in random.sample(faker_tags, random.randint(2, 5)): article.tags.append(tag) session.add(article) session.commit()
In the above code, we have created 10 users, 5 classification, 20 labels, 100 articles, and randomly selected 2 to 5 tags for each article.
Use SQLAlchemy add data to the database, we need to create an instance of the relevant class, call session.add()
to add one or session.add_all()
add more, and finally session.commit()
it.
5.2 Retrieve
If we know the user id, you can use get
methods filter_by
for filtering by a certain field, and filter
allows us to filter by multiple fields, all
is acquiring all.
Obtaining a class field value may be directly acquired attributes:
5.3 Update
Update a field:
>>> a = session.query(Article).get(10)
>>> a.title = 'My test blog post' >>> session.add(a) >>> session.commit()
Add a label:
>>> a = session.query(Article).get(10)
>>> a.tags.append(Tag(name='python')) >>> session.add(a) >>> session.commit()
5.4 Delete
>>> a = session.query(Article).get(10)
>>> session.delete(a) >>> session.commit()
Delete direct call to delete
the object to get deleted, you can submit session.
The complete code
# coding: utf-8
import random
from faker import Factory from sqlalchemy import create_engine, Table from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import ForeignKey from sqlalchemy import Column, String, Integer, Text from sqlalchemy.orm import sessionmaker, relationship engine = create_engine('mysql+mysqldb://root@localhost:3306/blog?charset=utf8') Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String(64), nullable=False, index=True) password = Column(String(64), nullable=False) email = Column(String(64), nullable=False, index=True) articles = relationship('Article', backref='author') userinfo = relationship('UserInfo', backref='user', uselist=False) def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.username) class UserInfo(Base): __tablename__ = 'userinfos' id = Column(Integer, primary_key=True) name = Column(String(64)) qq = Column(String(11)) phone = Column(String(11)) link = Column(String(64)) user_id = Column(Integer, ForeignKey('users.id')) class Article(Base): __tablename__ = 'articles' id = Column(Integer, primary_key=True) title = Column(String(255), nullable=False, index=True) content = Column(Text) user_id = Column(Integer, ForeignKey('users.id')) cate_id = Column(Integer, ForeignKey('categories.id')) tags = relationship('Tag', secondary='article_tag', backref='articles') def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.title) class Category(Base): __tablename__ = 'categories' id = Column(Integer, primary_key=True) name = Column(String(64), nullable=False, index=True) articles = relationship('Article', backref='category') def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.name) article_tag = Table( 'article_tag', Base.metadata, Column('article_id', Integer, ForeignKey('articles.id')), Column('tag_id', Integer, ForeignKey('tags.id')) ) class Tag(Base): __tablename__ = 'tags' id = Column(Integer, primary_key=True) name = Column(String(64), nullable=False, index=True) def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.name) if __name__ == '__main__': Base.metadata.create_all(engine) faker = Factory.create() Session = sessionmaker(bind=engine) session = Session() faker_users = [User( username=faker.name(), password=faker.word(), email=faker.email(), ) for i in range(10)] session.add_all(faker_users) faker_categories = [Category(name=faker.word()) for i