mtsql 1.8.202401021406__py3-none-any.whl → 1.9.202401091637__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
mt/sql/base.py CHANGED
@@ -1,5 +1,6 @@
1
1
  """Base functions dealing with an SQL database."""
2
2
 
3
+ import uuid
3
4
  import sqlalchemy as sa
4
5
  import sqlalchemy.exc as se
5
6
  import psycopg2 as ps
@@ -22,6 +23,7 @@ __all__ = [
22
23
  "list_tables",
23
24
  "list_views",
24
25
  "table_exists",
26
+ "create_temp_id_table",
25
27
  ]
26
28
 
27
29
 
@@ -43,7 +45,7 @@ def run_func(
43
45
  *args,
44
46
  nb_trials: int = 3,
45
47
  logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
46
- **kwargs
48
+ **kwargs,
47
49
  ):
48
50
  """Attempt to run a function a number of times to overcome OperationalError exceptions.
49
51
 
@@ -106,7 +108,7 @@ def read_sql(
106
108
  nb_trials: int = 3,
107
109
  exception_handling: str = "raise",
108
110
  logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
109
- **kwargs
111
+ **kwargs,
110
112
  ) -> pd.DataFrame:
111
113
  """Read an SQL query with a number of trials to overcome OperationalError.
112
114
 
@@ -174,7 +176,7 @@ def read_sql(
174
176
  chunksize=chunksize,
175
177
  nb_trials=nb_trials,
176
178
  logger=logger,
177
- **kwargs
179
+ **kwargs,
178
180
  )
179
181
 
180
182
  if chunksize is None:
@@ -214,7 +216,7 @@ def read_sql_table(
214
216
  engine,
215
217
  nb_trials: int = 3,
216
218
  logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
217
- **kwargs
219
+ **kwargs,
218
220
  ):
219
221
  """Read an SQL table with a number of trials to overcome OperationalError.
220
222
 
@@ -240,7 +242,7 @@ def read_sql_table(
240
242
  engine,
241
243
  nb_trials=nb_trials,
242
244
  logger=logger,
243
- **kwargs
245
+ **kwargs,
244
246
  )
245
247
 
246
248
 
@@ -250,7 +252,7 @@ def exec_sql(
250
252
  *args,
251
253
  nb_trials: int = 3,
252
254
  logger: tp.Optional[logg.IndentedLoggerAdapter] = None,
253
- **kwargs
255
+ **kwargs,
254
256
  ):
255
257
  """Execute an SQL query with a number of trials to overcome OperationalError.
256
258
 
@@ -356,3 +358,31 @@ def table_exists(
356
358
  """
357
359
 
358
360
  return sa.inspect(engine).has_table(table_name, schema=schema)
361
+
362
+
363
+ def create_temp_id_table(l_ids: list, conn: sa.engine.Connection) -> str:
364
+ """Creates a temporary table to containing a list of ids.
365
+
366
+ Parameters
367
+ ----------
368
+ l_ids : list
369
+ list of ids to be inserted into the table
370
+ conn : sqlalchemy.engine.Connection
371
+ a connection that has been opened
372
+
373
+ Returns
374
+ -------
375
+ table_name : str
376
+ name of the temporary table. The table will be deleted at the end of the connection
377
+ """
378
+
379
+ table_name = f"tab_{uuid.uuid4().hex}"
380
+
381
+ query_str = f"CREATE TEMP TABLE {table_name}(id int);"
382
+ conn.execute(sa.text(query_str))
383
+
384
+ values = ",".join((f"({id})" for id in l_ids))
385
+ query_str = f"INSERT INTO {table_name}(id) VALUES {values};"
386
+ conn.execute(sa.text(query_str))
387
+
388
+ return table_name
mt/sql/psql.py CHANGED
@@ -2004,11 +2004,9 @@ def readsync_table(
2004
2004
 
2005
2005
  if len(new_md5_df) != len(new_df):
2006
2006
  if logger:
2007
- logger.debug("New dataframe:\n{}".format(str(new_df)))
2008
- logger.debug("Hash dataframe:\n{}".format(str(new_md5_df)))
2009
- msg = "Something must have gone wrong. Number of hashes {} != number of records {}.".format(
2010
- len(new_md5_df), len(new_df)
2011
- )
2007
+ logger.debug(f"New dataframe:\n{str(new_df)}")
2008
+ logger.debug(f"Hash dataframe:\n{str(new_md5_df)}")
2009
+ msg = f"Something must have gone wrong. Number of hashes {len(new_md5_df)} != number of records {len(new_df)}."
2012
2010
  if raise_exception_upon_mismatch:
2013
2011
  raise RuntimeError(msg)
2014
2012
  elif logger:
@@ -2033,7 +2031,7 @@ def readsync_table(
2033
2031
 
2034
2032
  # write back
2035
2033
  if logger:
2036
- logger.debug("Saving all {} records to file...".format(len(df)))
2034
+ logger.debug(f"Saving all {len(df)} records to file...")
2037
2035
  if bg_write_csv is True:
2038
2036
  bg = BgInvoke(pd.dfsave, df, df_filepath, index=True)
2039
2037
  return df, bg
mt/sql/redshift.py CHANGED
@@ -507,10 +507,9 @@ def to_sql(
507
507
  **kwargs,
508
508
  )
509
509
 
510
- query_str = (
511
- f"ALTER TABLE {frame_sql_str} ADD PRIMARY KEY ({','.join(local_indices)});"
512
- )
513
- exec_sql(query_str, engine, nb_trials=nb_trials, logger=logger)
510
+ if if_exists == "replace":
511
+ query_str = f"ALTER TABLE {frame_sql_str} ADD PRIMARY KEY ({','.join(local_indices)});"
512
+ exec_sql(query_str, engine, nb_trials=nb_trials, logger=logger)
514
513
  else:
515
514
  retval = run_func(
516
515
  df.to_sql,
mt/sql/version.py CHANGED
@@ -1,11 +1,11 @@
1
1
  VERSION_YEAR = 2024
2
2
  VERSION_MONTH = int('01')
3
- VERSION_DAY = int('02')
4
- VERSION_HOUR = int('14')
5
- VERSION_MINUTE = int('06')
3
+ VERSION_DAY = int('09')
4
+ VERSION_HOUR = int('16')
5
+ VERSION_MINUTE = int('37')
6
6
  MAJOR_VERSION = 1
7
- MINOR_VERSION = 8
8
- PATCH_VERSION = 202401021406
9
- version_date = '2024/01/02 14:06'
7
+ MINOR_VERSION = 9
8
+ PATCH_VERSION = 202401091637
9
+ version_date = '2024/01/09 16:37'
10
10
  version = '{}.{}.{}'.format(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION)
11
11
  __all__ = ['MAJOR_VERSION', 'MINOR_VERSION', 'PATCH_VERSION', 'version_date', 'version']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mtsql
3
- Version: 1.8.202401021406
3
+ Version: 1.9.202401091637
4
4
  Summary: Extra Python modules to deal with the interaction between pandas dataframes and remote SQL servers, for Minh-Tri Pham
5
5
  Home-page: https://github.com/inteplus/mtsql
6
6
  Author: ['Minh-Tri Pham']
@@ -0,0 +1,12 @@
1
+ mt/sql/__init__.py,sha256=b7zO50apZxt9Hg2eOkJhRLrXgACR8eS5b-Rphdn5qNQ,44
2
+ mt/sql/base.py,sha256=GJLSQfz0GNXgFBzK6dSCVqQ4rjyTvFEBPmsM37d8eXc,10608
3
+ mt/sql/mysql.py,sha256=n2ENDctdUqZuSaDAcrqZYtPtawq3Wx4dOPCRsCB5Q4w,4894
4
+ mt/sql/psql.py,sha256=m41LsBQ57OVVtakUZ01o_YY-vBwY5Z3TVPvSUMylNaU,65964
5
+ mt/sql/redshift.py,sha256=EliV4C9E3VuNjqFXWnTrU8Dm_utQrVwht5DF4oHl7qY,14808
6
+ mt/sql/sqlite.py,sha256=T2ak_hhNi_zRfpg_gp8JhNHn7D2kl4i-Ey6-9ANMtz0,8678
7
+ mt/sql/version.py,sha256=nb0i2eAMsoLqFeLpvANq9ovAtp3TRIZsz2c02XZ4xBs,396
8
+ mtsql-1.9.202401091637.dist-info/LICENSE,sha256=PojkRlQzTT5Eg6Nj03XoIVEefN3u8iiIFf1p4rqe_t4,1070
9
+ mtsql-1.9.202401091637.dist-info/METADATA,sha256=0OS_X0KCiNKKzDFiiXTnttkBWJSeS6OoEsdmykC4JAc,589
10
+ mtsql-1.9.202401091637.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
11
+ mtsql-1.9.202401091637.dist-info/top_level.txt,sha256=WcqGFu9cV7iMZg09iam8eNxUvGpLSKKF2Iubf6SJVOo,3
12
+ mtsql-1.9.202401091637.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- mt/sql/__init__.py,sha256=b7zO50apZxt9Hg2eOkJhRLrXgACR8eS5b-Rphdn5qNQ,44
2
- mt/sql/base.py,sha256=FoK42rNDxVkqwtGiDJGvW1g02FJtSoqkMtbPlxBElA0,9780
3
- mt/sql/mysql.py,sha256=n2ENDctdUqZuSaDAcrqZYtPtawq3Wx4dOPCRsCB5Q4w,4894
4
- mt/sql/psql.py,sha256=JBdwPKwk1G6QzOJGRjUbIcxKosjPQ_PADG2VwDxCR4M,66036
5
- mt/sql/redshift.py,sha256=cDDSPUqy6vIyKcKUNsQnZLESGLhgC8NYGyyIWhFTrNk,14789
6
- mt/sql/sqlite.py,sha256=T2ak_hhNi_zRfpg_gp8JhNHn7D2kl4i-Ey6-9ANMtz0,8678
7
- mt/sql/version.py,sha256=gnhJJ-02mxUSXuUdVmoieNHefSOLt5692teFJSVykOA,396
8
- mtsql-1.8.202401021406.dist-info/LICENSE,sha256=PojkRlQzTT5Eg6Nj03XoIVEefN3u8iiIFf1p4rqe_t4,1070
9
- mtsql-1.8.202401021406.dist-info/METADATA,sha256=vlwY4ZndshEQJY6Ux4D1N907fFbl7b_7K1erSDkPkuA,589
10
- mtsql-1.8.202401021406.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
11
- mtsql-1.8.202401021406.dist-info/top_level.txt,sha256=WcqGFu9cV7iMZg09iam8eNxUvGpLSKKF2Iubf6SJVOo,3
12
- mtsql-1.8.202401021406.dist-info/RECORD,,