def test_array_dumper(conn, fmt_out): t = Transformer(conn) fmt_in = Format.from_pq(fmt_out) dint = t.get_dumper([0], fmt_in) assert dint.oid == builtins["int2"].array_oid assert dint.sub_dumper.oid == builtins["int2"].oid dstr = t.get_dumper([""], fmt_in) if fmt_in == Format.BINARY: assert dstr.oid == builtins["text"].array_oid assert dstr.sub_dumper.oid == builtins["text"].oid else: assert dstr.oid == 0 assert dstr.sub_dumper.oid == 0 assert dstr is not dint assert t.get_dumper([1], fmt_in) is dint assert t.get_dumper([None, [1]], fmt_in) is dint dempty = t.get_dumper([], fmt_in) assert t.get_dumper([None, [None]], fmt_in) is dempty assert dempty.oid == 0 assert dempty.dump([]) == b"{}" L = [] L.append(L) with pytest.raises(psycopg3.DataError): assert t.get_dumper(L, fmt_in)
async def test_copy_to_leaks(dsn, faker, fmt, method): faker.format = PgFormat.from_pq(fmt) faker.choose_schema(ncols=20) faker.make_records(20) n = [] for i in range(3): async with await psycopg3.AsyncConnection.connect(dsn) as conn: async with conn.cursor(binary=fmt) as cur: await cur.execute(faker.drop_stmt) await cur.execute(faker.create_stmt) await cur.executemany(faker.insert_stmt, faker.records) stmt = sql.SQL( "copy (select {} from {} order by id) to stdout (format {})" ).format( sql.SQL(", ").join(faker.fields_names), faker.table_name, sql.SQL(fmt.name), ) async with cur.copy(stmt) as copy: types = [ t.as_string(conn).replace('"', "") for t in faker.types_names ] copy.set_types(types) if method == "read": while 1: tmp = await copy.read() if not tmp: break elif method == "iter": async for x in copy: pass elif method == "row": while 1: tmp = await copy.read_row() if tmp is None: break elif method == "rows": async for x in copy.rows(): pass tmp = None del cur, conn gc.collect() gc.collect() n.append(len(gc.get_objects())) assert ( n[0] == n[1] == n[2] ), f"objects leaked: {n[1] - n[0]}, {n[2] - n[1]}"
async def test_copy_from_leaks(dsn, faker, fmt): faker.format = PgFormat.from_pq(fmt) faker.choose_schema(ncols=20) faker.make_records(20) n = [] for i in range(3): async with await psycopg3.AsyncConnection.connect(dsn) as conn: async with conn.cursor(binary=fmt) as cur: await cur.execute(faker.drop_stmt) await cur.execute(faker.create_stmt) stmt = sql.SQL("copy {} ({}) from stdin (format {})").format( faker.table_name, sql.SQL(", ").join(faker.fields_names), sql.SQL(fmt.name), ) async with cur.copy(stmt) as copy: for row in faker.records: await copy.write_row(row) await cur.execute(faker.select_stmt) recs = await cur.fetchall() for got, want in zip(recs, faker.records): faker.assert_record(got, want) del recs del cur, conn gc.collect() gc.collect() n.append(len(gc.get_objects())) assert ( n[0] == n[1] == n[2] ), f"objects leaked: {n[1] - n[0]}, {n[2] - n[1]}"