Default repository for execsql.py
Révision | b170da182a8892c67ce0c9bd6656ff3ca00d8508 (tree) |
---|---|
l'heure | 2020-02-09 02:35:20 |
Auteur | Dreas Nielsen <dnielsen@inte...> |
Commiter | Dreas Nielsen |
Made encoding for access controlled by a flag for Jet version.
@@ -27,12 +27,12 @@ | ||
27 | 27 | # |
28 | 28 | # =============================================================================== |
29 | 29 | |
30 | -__version__ = "1.61.5" | |
31 | -__vdate = "2020-02-06" | |
30 | +__version__ = "1.61.7" | |
31 | +__vdate = "2020-02-08" | |
32 | 32 | |
33 | 33 | primary_vno = 1 |
34 | 34 | secondary_vno = 61 |
35 | -tertiary_vno = 5 | |
35 | +tertiary_vno = 7 | |
36 | 36 | |
37 | 37 | import os |
38 | 38 | import os.path |
@@ -3083,11 +3083,13 @@ | ||
3083 | 3083 | class AccessDatabase(Database): |
3084 | 3084 | # Regex for the 'create temporary view' SQL extension |
3085 | 3085 | temp_rx = re.compile(r'^\s*create(?:\s+or\s+replace)?(\s+temp(?:orary)?)?\s+(?:(view|query))\s+(\w+) as\s+', re.I) |
3086 | + # Connection strings are a tuple, where the first part is the connection string and the second part is | |
3087 | + # a flag indicating whether this driver uses Jet 4. | |
3086 | 3088 | connection_strings = ( |
3087 | - "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;ExtendedAnsiSQL=1;", | |
3088 | - "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=%s;", | |
3089 | - "Provider=Microsoft.ACE.OLEDB.15.0; Data Source=%s;", | |
3090 | - "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=%s;" | |
3089 | + ("DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;ExtendedAnsiSQL=1;", True), | |
3090 | + ("DRIVER={Microsoft Access Driver (*.mdb)};DBQ=%s;", False), | |
3091 | + ("Provider=Microsoft.ACE.OLEDB.15.0; Data Source=%s;", True), | |
3092 | + ("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=%s;", True) | |
3091 | 3093 | ) |
3092 | 3094 | def __init__(self, Access_fn, need_passwd=False, user_name=None, encoding=None, password=None): |
3093 | 3095 | global pyodbc |
@@ -3103,9 +3105,12 @@ | ||
3103 | 3105 | self.type = dbt_access |
3104 | 3106 | self.server_name = None |
3105 | 3107 | self.db_name = Access_fn |
3108 | + # The following assignment is tentative and may be changed when the connection is made. | |
3109 | + self.jet4 = len(Access_fn) > 6 and Access_fn.lower()[-6:] == '.accdb' | |
3106 | 3110 | self.user = user_name |
3107 | 3111 | self.need_passwd = need_passwd |
3108 | 3112 | self.password = password |
3113 | + # Encoding is only applicable to Jet < 4.0: non-accdb databases. | |
3109 | 3114 | self.encoding = encoding or 'windows_1252' |
3110 | 3115 | self.encode_commands = True |
3111 | 3116 | self.dao_conn = None |
@@ -3132,7 +3137,7 @@ | ||
3132 | 3137 | self.password = get_password("MS-Access", self.db_name, self.user) |
3133 | 3138 | connected = False |
3134 | 3139 | db_name = os.path.abspath(self.db_name) |
3135 | - for cs in self.connection_strings: | |
3140 | + for cs, jet4flag in self.connection_strings: | |
3136 | 3141 | if self.need_passwd: |
3137 | 3142 | connstr = "%s Uid=%s; Pwd=%s;" % (cs % db_name, self.user, self.password) |
3138 | 3143 | else: |
@@ -3143,6 +3148,7 @@ | ||
3143 | 3148 | exec_log.log_status_info(u"Could not connect via ODBC using: %s" % connstr) |
3144 | 3149 | else: |
3145 | 3150 | exec_log.log_status_info(u"Connected via ODBC using: %s" % connstr) |
3151 | + self.jet4 = jet4flag | |
3146 | 3152 | connected = True |
3147 | 3153 | break |
3148 | 3154 | if not connected: |
@@ -3200,9 +3206,12 @@ | ||
3200 | 3206 | def exec1(sql, paramlist): |
3201 | 3207 | tqd = self.temp_rx.match(sql) |
3202 | 3208 | if tqd: |
3203 | - #qn = tqd.group(3).encode(self.encoding) | |
3204 | - qn = tqd.group(3) | |
3205 | - qsql = sql[tqd.end():].encode(self.encoding) | |
3209 | + if self.jet4: | |
3210 | + qn = tqd.group(3) | |
3211 | + qsql = sql[tqd.end():] | |
3212 | + else: | |
3213 | + qn = tqd.group(3).encode(self.encoding) | |
3214 | + qsql = sql[tqd.end():].encode(self.encoding) | |
3206 | 3215 | if self.dao_conn is None: |
3207 | 3216 | self.open_dao() |
3208 | 3217 | try: |
@@ -3221,17 +3230,24 @@ | ||
3221 | 3230 | else: |
3222 | 3231 | self.dao_flush_check() |
3223 | 3232 | curs = self.cursor() |
3224 | - encoded_sql = type(u"")(sql).encode(self.encoding) | |
3225 | - if sys.version_info < (3,): | |
3226 | - if paramlist is None: | |
3227 | - curs.execute(encoded_sql) | |
3228 | - else: | |
3229 | - curs.execute(encoded_sql, paramlist) | |
3233 | + if self.jet4: | |
3234 | + encoded_sql = type(u"")(sql) | |
3230 | 3235 | else: |
3231 | - if paramlist is None: | |
3232 | - curs.execute(encoded_sql.decode(self.encoding)) | |
3233 | - else: | |
3234 | - curs.execute(encoded_sql.decode(self.encoding), paramlist) | |
3236 | + encoded_sql = type(u"")(sql).encode(self.encoding) | |
3237 | + if paramlist is None: | |
3238 | + curs.execute(encoded_sql) | |
3239 | + else: | |
3240 | + curs.execute(encoded_sql, paramlist) | |
3241 | + #if sys.version_info < (3,): | |
3242 | + # if paramlist is None: | |
3243 | + # curs.execute(encoded_sql) | |
3244 | + # else: | |
3245 | + # curs.execute(encoded_sql, paramlist) | |
3246 | + #else: | |
3247 | + # if paramlist is None: | |
3248 | + # curs.execute(encoded_sql.decode(self.encoding)) | |
3249 | + # else: | |
3250 | + # curs.execute(encoded_sql.decode(self.encoding), paramlist) | |
3235 | 3251 | subvars.add_substitution("$LAST_ROWCOUNT", curs.rowcount) |
3236 | 3252 | if type(sqlcmd) in (list, tuple): |
3237 | 3253 | for sql in sqlcmd: |
@@ -4,7 +4,7 @@ | ||
4 | 4 | long_description = f.read() |
5 | 5 | |
6 | 6 | setuptools.setup(name='execsql', |
7 | - version='1.61.5', | |
7 | + version='1.61.7', | |
8 | 8 | description="Runs a SQL script against a PostgreSQL, MS-Access, SQLite, MS-SQL-Server, MySQL, MariaDB, Firebird, or Oracle database, or an ODBC DSN. Provides metacommands to import and export data, copy data between databases, conditionally execute SQL and metacommands, and dynamically alter SQL and metacommands with substitution variables. Data can be exported in 13 different formats, including CSV, TSV, ODS, HTML, JSON, LaTeX, and Markdown tables, and using custom templates.", |
9 | 9 | author='Dreas Nielsen', |
10 | 10 | author_email='dreas.nielsen@gmail.com', |