Phương thức Python đơn giản dùng mãi mãi để thực thi / chạy


8

Mã của tôi bị kẹt ở clean_up()phương thức trongMyClass()

my_group.py:

import os
import pandas as pd
import psycopg2, pymysql, pyodbc
from db_credentials_dict import db_credentials

class MyClass():

    def __init__(self, from_database, to_table_name, report_name):
        ...

    def get_sql(self):
        ...

    def get_connection(self):
        ...

    def query_to_csv(self):
        ...

    def csv_to_postgres(self):
        ...

    def extract_and_load(self):
        self.query_to_csv()
        self.csv_to_postgres()

    def get_final_sql(self):
        ...

    def postgres_to_csv(self):
        ...

    def clean_up(self):
        print('\nTruncating {}...'.format(self.to_table_name), end='')
        with self.postgres_connection.cursor() as cursor:
            cursor.execute("SELECT NOT EXISTS (SELECT 1 FROM %s)" % self.to_table_name)
            empty = cursor.fetchone()[0]
            if not empty:
                cursor.execute("TRUNCATE TABLE %s" % self.to_table_name)
        self.postgres_connection.commit()
        print('DONE')

        print('Removing {}...'.format(self.filename), end='')
        if os.path.exists(self.filepath):
            os.remove(self.filepath)
            print('DONE')
        else:
            print('{} does not exist'.format(self.filename))

chính:

from my_class import MyClass
from time import sleep

bookings = MyClass(from_database='...',to_table_name='...',report_name='...')
bookings2 = MyClass(from_database='...',to_table_name='...',report_name='...')
channel = MyClass(from_database='...',to_table_name='...',report_name='...')
cost = MyClass(from_database='...',to_table_name='...',report_name='...')

tables = [bookings, bookings2, channel, cost]
for table in tables:
    table.extract_and_load()

daily_report = MyClass(from_database='...',to_table_name='...',report_name='...')
daily_report.postgres_to_csv()
sleep(10)

for table in tables:
    table.clean_up()

Khi tôi chạy, main.pynó chạy mọi thứ cho đến vòng lặp cuối cùng for table in tables: table.clean_up(). Nó chỉ bị mắc kẹt ở đó, không có lỗi hoặc cảnh báo.

Khi chạy phương thức đó, nó hoạt động tốt, tức là nó cắt các bảng postgres. Cần trợ giúp để làm việc này và hiểu lý do tại sao phương thức cuối cùng không thực thi khi tất cả các phương thức khác được thực thi.

Đầu ra của khi tự chạy clean_up():

Truncating bookings...DONE
Removing bookings.csv...DONE

Truncating bookings2...DONE
Removing bookings2.csv...DONE

Truncating channel...DONE
Removing channel.csv...DONE

Truncating cost...DONE
Removing cost.csv...DONE

Mã tổng thể làm gì:

  1. Lấy các tệp có chứa các truy vấn sql trích xuất dữ liệu từ các cơ sở dữ liệu khác nhau và thực hiện các truy vấn đó.
  2. Xuất chúng sang csv
  3. Nhập csv vào cơ sở dữ liệu postgres
  4. Viết một truy vấn postgres mang dữ liệu lại với nhau và sau đó xuất dưới dạng csv được sử dụng trong công cụ BI để trực quan hóa dữ liệu
  5. Cắt bớt dữ liệu trong postgres và xóa các tệp csv ở điểm 2

Có lẽ bạn đang nghĩ rằng đây là một sự điên rồ và tôi đồng ý. Tôi hiện đang thực hiện với những gì tôi đã nhận và không thể lưu trữ dữ liệu trên máy tính của mình vì đó là dữ liệu của công ty (do đó việc cắt và xóa dữ liệu).


2
Tôi không thể thấy bất cứ điều gì gây ra vấn đề này trong những gì bạn đã đăng mã Python của mình, vì vậy vấn đề rất có thể xảy ra với postgres.
bruno Desthuilliers

bạn có thể đăng kết quả đầu ra của phương thức Clean_up () khi chạy riêng không?
kederrac

Câu trả lời:


5

TRUNCATEmệnh đề trong Postgres yêu cầu ACCESS EXCLUSIVEkhóa về mối quan hệ và cũng có thể BEFORE TRUNCATEkích hoạt một số kích hoạt.

Tôi đoán là vấn đề nằm ở phía Postgres, ví dụ như TRUNCATEcố gắng có được ACCESS EXCLUSIVEkhóa trên mối quan hệ, nhưng nó đã bị khóa bởi người khác.

Đầu tiên, hãy kiểm tra nhật ký Postgres của bạn.

Tiếp theo, hãy kiểm tra xem phần phụ trợ Postgres của bạn đang làm gì trong khi bị treo TRUNCATEvới:

SELECT * FROM pg_stat_activity;

Tiếp theo, điều tra các khóa với:

-- View with readable locks info and filtered out locks on system tables
CREATE VIEW active_locks AS
SELECT clock_timestamp(), pg_class.relname, pg_locks.locktype, pg_locks.database,
       pg_locks.relation, pg_locks.page, pg_locks.tuple, pg_locks.virtualtransaction,
       pg_locks.pid, pg_locks.mode, pg_locks.granted
FROM pg_locks JOIN pg_class ON pg_locks.relation = pg_class.oid
WHERE relname !~ '^pg_' and relname <> 'active_locks';

-- Now when we want to see locks just type
SELECT * FROM active_locks;

Cám ơn vì cái này. Tôi đã tạo chế độ xem như bạn đã hiển thị, đầu ra trống
AK91

OK, pg_stat_activity là gì? Những phụ trợ khác đang làm gì? Ví dụ vớiSELECT * FROM pg_stat_activity WHERE backend_type = 'client backend' AND datname IS NOT NULL;
ololobus

2

Tôi sẽ đề nghị bạn thực hiện quy trình sạch mong muốn tất cả trong một giao dịch. Để ngăn chặn các quốc gia không mong muốn.

Và kiểm tra Nếu bảng tồn tại trong cơ sở dữ liệu bằng cách sử dụng information_schema

SELECT EXISTS (
   SELECT 1
   FROM   information_schema.tables 
   WHERE  table_schema = 'schema_name'
   AND    table_name = 'table_name'
   );

Kiểm tra Nếu tồn tại, tạo các lệnh cắt ngắn của bạn.

và thực hiện quy trình sạch tất cả trong một giao dịch.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.