Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用create_引擎将SQLAlchemy转换为MSSQL_Python_Sql Server_Pandas_Sqlalchemy - Fatal编程技术网

Python 使用create_引擎将SQLAlchemy转换为MSSQL

Python 使用create_引擎将SQLAlchemy转换为MSSQL,python,sql-server,pandas,sqlalchemy,Python,Sql Server,Pandas,Sqlalchemy,我能找到的大多数用Python显示完整MSSQL连接方法的示例在几个月前已经过时,部分原因是SQLAlchemy中的一些优化。我试图复制我在文档中看到的内容 我无法使用pyodbc将SQLAlchemy连接到MSSQL Server。 我有一个本地SQL server,可从以下位置的SQL server Management Studio访问:#DESKTOP-QLSOTTG\SQLEXPRESS 数据库是:TestDB 本例中的用户名为:TestUser 本例中的密码为:TestUserPas

我能找到的大多数用Python显示完整MSSQL连接方法的示例在几个月前已经过时,部分原因是SQLAlchemy中的一些优化。我试图复制我在文档中看到的内容

我无法使用pyodbc将SQLAlchemy连接到MSSQL Server。

我有一个本地SQL server,可从以下位置的SQL server Management Studio访问:#DESKTOP-QLSOTTG\SQLEXPRESS
数据库是:TestDB
本例中的用户名为:TestUser
本例中的密码为:TestUserPass

我想运行一个将pandas数据帧导入MSSQL数据库的测试用例(cases?),以找出最快的方法。然而,这个问题的目的是围绕连通性

信贷:我从Gord那里借了一些代码用于数据帧/更新

我收到的错误如下。我将假设服务器“主动拒绝连接”是因为我的连接字符串不知怎么搞砸了,但我似乎不明白原因

OperationalError: (pyodbc.OperationalError) ('08001', '[08001] [Microsoft][ODBC Driver 13 for SQL Server]TCP Provider: No connection could be made because the target machine actively refused it.\r\n (10061) (SQLDriverConnect); [08001] [Microsoft][ODBC Driver 13 for SQL Server]Login timeout expired (0); [08001] [Microsoft][ODBC Driver 13 for SQL Server]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. (10061)')
(Background on this error at: http://sqlalche.me/e/13/e3q8)
可以从SQL Server Management Studio连接数据库和用户。*

关于我可能遗漏的内容有什么想法吗?

注意事项:

  • 将DESKTOP-QLSOTTG\SQLEXPRESS:1433更改为DESKTOP-QLSOTTG:1433未更改错误
  • 将DESKTOP-QLSOTTG\SQLEXPRESS:1433更改为localhost:1433不会更改错误
  • 将DESKTOP-QLSOTTG\SQLEXPRESS:1433更改为localhost\SQLEXPRESS:1433不会更改错误

您需要启用TCP/IP

在开始菜单上,单击所有程序>Microsoft SQL Server 2012>配置工具>SQL Server配置管理器。 单击SQL Server 2012服务

展开SQL Server 2012网络配置节点,然后选择MSSQLServer的协议(SQL实例名称)

右键单击TCP/IP,然后单击启用

在树中选择SQL Server 2012服务。
右键单击SQL Server(SQL实例名称),然后单击Restart(重新启动)

我将用一个完整的示例来回答这个问题,因为在此过程中我遇到了一些其他问题

此示例能够:

  • 使用fast\u executemany和用户指定的内存友好分块将数据快速加载到MS SQL数据库
  • 在大约0.3秒内将10000条记录(25列)加载到Microsoft SQL(MSSQL)数据库
  • 在大约45秒内将1000000条记录(25列)加载到Microsoft SQL(MSSQL)数据库
  • 在大约9分钟内将10000000条记录(25列)加载到Microsoft SQL(MSSQL)数据库
  • 使用预配置的函数分块数据,该函数可避免使用chunksize,这会在较大的数据集上导致内存错误。用于分块
  • 可以帮助您将数据加载到ram较低的SQL server中。大容量加载占用大量ram,较小的加载大小占用的内存要少得多
  • 可以添加一个try/except语句来捕获您正在尝试记录的块的加载错误/稍后重试类型设置
我已经为一些其他的DB提供者提供了一些未经测试的连接字符串。 截至2020年12月,pandas、sqlalchemy、pyodbc等的当前版本

%%time #remove this if you are not using a Jupyter notebook and just want to run a .py script

import pandas as pd
import numpy as np
import sqlalchemy as sql
import sys
import math

# Enterprise DB to be used
DRIVER = "ODBC Driver 17 for SQL Server"
USERNAME = "TestUser"
PSSWD = "TestUser"
SERVERNAME = "DESKTOP-QLSOTTG"
INSTANCENAME = "\SQLEXPRESS"
DB = "TestDB"
TABLE = "perftest"


conn_executemany = sql.create_engine(
    f"mssql+pyodbc://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}?driver={DRIVER}", fast_executemany=True
)



def chunker(seq, size):
    return (seq[pos : pos + size] for pos in range(0, len(seq), size))


def insert_with_progress(df, engine, table="", schema=""):
    con = engine.connect()

    # Replace table
    engine.execute(f"DROP TABLE IF EXISTS {schema}.{table};")

    # Insert with progress
    SQL_SERVER_CHUNK_LIMIT = 100000
    chunksize = math.floor(SQL_SERVER_CHUNK_LIMIT / len(df.columns))

    for chunk in chunker(df, chunksize):
        chunk.to_sql(
            name=table,
            con=con,
            if_exists="append",
            index=False
        )
        
df = pd.DataFrame(np.random.random((10 ** 7, 24)))
df['TextCol'] = "Test Goes Here"
df.head()
print("DataFrame is", round(sys.getsizeof(df) / 1024 ** 2, 1), "MB")
print("DataFrame contains", len(df), "rows by", len(df.columns), "columns")


# Doing it like this errors out. Can't seem to be able to debug the straight pandas call.
# df.to_sql(TABLE, conn_sqlalchemy, index=False, if_exists='replace', method='multi', chunksize=2100)

insert_with_progress(df, conn_executemany, table=TABLE)
关于连接字符串:

  • 如果希望更改为另一种DB类型,则最有可能只需要更改以
    f“mssql+pyodbc://
    开头的行
  • 如果SQL server不使用实例名称(例如SQLSERVERNAME\instance\u name),则可以将实例名称参数设置为空
  • 如果确实使用实例名,请确保在变量开头保留\
  • 如果使用不同的连接字符串,还需要在上面的代码窗口的最后一行用连接字符串名称替换变量名称
  • 其他提供商的替代包含声明
    这些措施包括:

    • pymssql
    • turbobdc
    备用连接字符串
    对于DSN样式的字符串,我已将其修改为使用用户名/密码

    conn_sqlalchemy = sql.create_engine(f"mssql+pyodbc://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}?driver={DRIVER}")
    
    conn_executemany = sql.create_engine(
        f"mssql+pyodbc://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}?driver={DRIVER}", fast_executemany=True
    )
    
    conn_turbodbc = sql.create_engine(f"mssql+turbodbc://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}?driver={DRIVER}")
    
    conn_pymssql = sql.create_engine(f"mssql+pymssql://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}")
    

    谢谢-虽然这并没有解决测试问题。我想,因为我可以使用SSMS进行连接,所以如果这是您注意到的问题,我也会面临同样的问题。未来的读者应该注意:(1)SQL Server Express Edition(SQLEXPRESS)的默认安装不会侦听端口1433,以及(2)在指定SQL Server实例时,应该使用
    Server\u NAME\instance\u NAME
    Server\u NAME:PORT\u NUMBER
    ,而不是两者都使用。谢谢@GordThompson,这是一个很好的观点。我相信这同样适用于新术语下的SQL Developer Edition。
    import pymssql as ms
    import sqlalchemy as sql
    import sqlalchemy_turbodbc as st
    
    conn_sqlalchemy = sql.create_engine(f"mssql+pyodbc://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}?driver={DRIVER}")
    
    conn_executemany = sql.create_engine(
        f"mssql+pyodbc://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}?driver={DRIVER}", fast_executemany=True
    )
    
    conn_turbodbc = sql.create_engine(f"mssql+turbodbc://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}?driver={DRIVER}")
    
    conn_pymssql = sql.create_engine(f"mssql+pymssql://{USERNAME}:{PSSWD}@{SERVERNAME}{INSTANCENAME}/{DB}")