<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>编程语言 on bugwang</title>
    <link>https://bugwang.cn/categories/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/</link>
    <description>Recent content in 编程语言 on bugwang</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-ch</language>
    <lastBuildDate>Tue, 04 Jun 2024 11:22:01 +0800</lastBuildDate><atom:link href="https://bugwang.cn/categories/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>SQLAlchemy快速上手</title>
      <link>https://bugwang.cn/posts/sqlalchemy%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/</link>
      <pubDate>Tue, 04 Jun 2024 11:22:01 +0800</pubDate>
      
      <guid>https://bugwang.cn/posts/sqlalchemy%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/</guid>
      <description>SQLAlchemy 演示插入数据代码
import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column,Integer,String from sqlalchemy.orm import sessionmaker #创建对象的基类： Base = declarative_base() #定义User对象： class User(Base): #表的名字： __tablename__ = &amp;#39;user&amp;#39; #表的结构: userid = Column(Integer,primary_key=True) username = Column(String(20)) age = Column(Integer) department = Column(String(20)) #初始化数据库连接 engine = create_engine(&amp;#34;mysql+pymysql://kang:123456@10.3.152.35/test&amp;#34;,encoding=&amp;#34;utf-8&amp;#34;,echo=True) #创建session类型 DBSession = sessionmaker(bind=engine) #创建session对象 session = DBSession() #创建新的user对象 new_user1 = User(username=&amp;#39;CC&amp;#39;,age=25,department=&amp;#39;IT&amp;#39;) new_user2 = User(username=&amp;#34;LILI&amp;#34;,age=30,department=&amp;#39;HR&amp;#39;) new_user3 = User(username=&amp;#39;JOHN&amp;#39;,age=22,department=&amp;#39;IT&amp;#39;) #添加单条数据（添加数据，但还没有提交，出错还可以使用rollback撤回操作） new_user = User(name=&amp;#39;lily&amp;#39;) #session.</description>
    </item>
    
    <item>
      <title>重新理解AsyncIO</title>
      <link>https://bugwang.cn/posts/%E9%87%8D%E6%96%B0%E7%90%86%E8%A7%A3asyncio/</link>
      <pubDate>Tue, 04 Jun 2024 10:17:11 +0800</pubDate>
      
      <guid>https://bugwang.cn/posts/%E9%87%8D%E6%96%B0%E7%90%86%E8%A7%A3asyncio/</guid>
      <description>1.概要 python下的协程 asyncio和gevent都是基于携程来进行并发操作的。协程也被称为微线程。 协程只是在单一的线程里进行切换不同的协程，因此无法使用多CPU能力，对于CPU密集型程序还是使用多进程比较好。 协程相比较进程和线程来说占用的内容更少，同样的线程切换更多的是靠操作系统来控制，而协程的执行则由我们自己控制。
并发与异步区分 并发原理：当其中一个协程遇到io等待时，将会切换到另一个协程继续运行。
并发与异步：
并发强调的是N人干同样的事，要保证不争抢 (lock，atomic，synchronize，volatile, cas)
异步强调的是1/N人干不同的事，不该等的别等 (thread pool, future, async,reactive)
看到并发的时候经常会看到异步，原因是一般所说的并发，指的是 【每个业务活动频率很低，但是有大量同时进行的业务活动】 这样用异步代码自己维护每个业务状态，而不劳驾系统通过线程/进程的方式维护每个业务状态的方式，能把这个场景实现得性能更好，内存占用更少。 如果业务活动频率又高，又同时大量进行，那就超出异步的解决范围了。那是分布式处理的范畴。 需要协程原因 1.多线程运行过程容易被打断，有可能出现race condition的情况 2.线程切换本身存在定的消耗，若/0操作非常heavy，多线程很有可能满足不了高效率、高质量的需求。
sync和async的概念区分 sync即同步，指操作个接个地执行，下一个操作必须等上一个操作完成后才能执行。 asynd即异步，指不同的操作可以交替执行，如果其中某个操作被block了，程序并不会等待，而是会找出可执行的操作继续执行。 Asyncio的缺陷 在实际工作中，要想用好Asyncio，必须得有相应的python库支持。在之前的多线程例子中，我们用到的是requests库，而在这里使用的却是aiohttp库，原因就在于requests库与Asyncio不兼容，但aiohttp库兼容。但是兼容问题会随着版本的问题逐步减少。
此外，使用Asyncio使得我们在任务调度方面有更大的自主权，写代码时就得更加注意，否则容易出现错误。
比如，如果你需要await一系列的操作，就得使用asyncio.gather()；如果只是单个的future，则用asyncio.wait()就可以了。那么，对于你的future，是想让它run_until_complete()还是run_forever()呢？此类问题都是在面对具体问题时需要去考虑的。
那么使用asyncio时 如何搭配第三方库 首先，最简单的办法就是搜一下这个库的源码里是否出现了 asyncio 或 async def 的字样，如果没有出现则几乎可以证明这个库没有对 asyncio 有做特别的支持。为了彻底证实，还应仔细阅读其代码，查看关键 I/O 部分是如何实现的。
对于暂不支持 asyncio 的第三方库，可以按以下步骤依次排查：
1. 确认其 I/O 时间比例是否占到大部分。比如用 SQLAlchemy 时，如果能基本上确保数据库操作都是瞬时的，那么[理论上](http://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/)是可以任由其阻塞主线程的。而对于明显 I/O 占大多数时间且时间不可预测的，比如 requests，就不能让其成为性能瓶颈； 2. 确认其 I/O 的并发能力是否会成为瓶颈。比如说还是用到了 requests，但平均下来每 10 分钟才会发一个请求，其他时间主要都用在数据库计算上了，那么完全可以把 requests [放到线程池里](https://docs.python.org/3/library/asyncio-eventloop.html#executor)去做； 3. 确实需要异步了，首先查找其 asyncio 的扩展，有时会有单独的库做 asyncio 支持，比如 peewee_async； 4.</description>
    </item>
    
    <item>
      <title>Alembic数据库迁移工具使用</title>
      <link>https://bugwang.cn/posts/alembic%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%81%E7%A7%BB%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/</link>
      <pubDate>Fri, 04 Jun 2021 10:56:51 +0800</pubDate>
      
      <guid>https://bugwang.cn/posts/alembic%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%81%E7%A7%BB%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/</guid>
      <description>背景 在很多时候，在我们设计好模型之后，又需要进行一定的改变和更新数据操作；最直接的方式就是删除原来的旧表，但我们之前的数据也会删除；究其原因是我们不能精确记住每个修改和对应DDL，这时候就需要数据库迁移框架了。
对于Django ，框架内部就集成了数据库迁移模块，我们可以很方便使用
回顾Django迁移命令： 基本语法： python manage.py xx [app_name] xx如下： migrate，负责应用和撤销迁移。 makemigrations，基于模型的修改创建迁移。 sqlmigrate，展示迁移使用的 SQL 语句。 showmigrations，列出项目的迁移和迁移的状态。 Django迁移过程分为3步走： 1:修改models数据模型 2:生成迁移文件（在migrations/文件夹下）python manage.py makemigrations 3:向数据库执行迁移操作：python manage.py migrate 总结，迁移数据库的主要思路： 1：修改数据模型 2：生成新迁移文件 3：执行迁移 那么在Flask + SQLAlchemy下，如何选择数据库管理迁移工具？
Alembic介绍 Alembic是Sqlalchemy的作者就已经实现的一个数据库版本化管理工具：
Alembic来帮助我们实现数据库的迁移，数据库迁移工具可以在不破坏数据的情况下更新数据库表的结构。蒸馏器（Alembic）是炼金术士最重要的工具，要学习SQL炼金术（SQLAlchemy），当然要掌握蒸馏器的使用。
Alembic 是一个处理数据库更改的工具，它利用 SQLAlchemy 来实现形成迁移。因为 SQLAlchemy 只会在我们使用时根据 metadata create_all 方法来创建缺少的表 ，它不会根据我们对代码的修改而更新数据库表中的列。它也不会自动帮助我们删除表。 Alembic 提供了一种更新 / 删除表，更改列名和添加新约束的方法。因为 Alembic 使用 SQLAlchemy 执行迁移，它们可用于各种后端数据库。
快速上手 # 安装alembic pip install alembic # 初次使用时，需要初始化，创建迁移环境和 alembic.ini 文件、env.py文件 alembic init migrations # 修改alembic.ini配置，改变 sqlalchemy.url 值，配置数据库连接。 sqlalchemy.</description>
    </item>
    
  </channel>
</rss>
